// 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 script provides access to the Apps Script API.
//
// For product documentation, see: https://developers.google.com/apps-script/api/
//
// Creating a client
//
// Usage example:
//
//   import "google.golang.org/api/script/v1"
//   ...
//   ctx := context.Background()
//   scriptService, err := script.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
//
// By default, all available scopes (see "Constants") are used to authenticate. To restrict scopes, use option.WithScopes:
//
//   scriptService, err := script.NewService(ctx, option.WithScopes(script.UserinfoEmailScope))
//
// To use an API key for authentication (note: some APIs do not support API keys), use option.WithAPIKey:
//
//   scriptService, err := script.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, ...)
//   scriptService, err := script.NewService(ctx, option.WithTokenSource(config.TokenSource(ctx, token)))
//
// See https://godoc.org/google.golang.org/api/option/ for details on options.
package script // import "google.golang.org/api/script/v1"

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

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

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

const apiId = "script:v1"
const apiName = "script"
const apiVersion = "v1"
const basePath = "https://script.googleapis.com/"

// OAuth2 scopes used by this API.
const (
	// Read, compose, send, and permanently delete all your email from Gmail
	MailGoogleComScope = "https://mail.google.com/"

	// See, edit, share, and permanently delete all the calendars you can
	// access using Google Calendar
	WwwGoogleComCalendarFeedsScope = "https://www.google.com/calendar/feeds"

	// See, edit, download, and permanently delete your contacts
	WwwGoogleComM8FeedsScope = "https://www.google.com/m8/feeds"

	// View and manage the provisioning of groups on your domain
	AdminDirectoryGroupScope = "https://www.googleapis.com/auth/admin.directory.group"

	// View and manage the provisioning of users on your domain
	AdminDirectoryUserScope = "https://www.googleapis.com/auth/admin.directory.user"

	// View and manage your Google Docs documents
	DocumentsScope = "https://www.googleapis.com/auth/documents"

	// See, edit, create, and delete all of your Google Drive files
	DriveScope = "https://www.googleapis.com/auth/drive"

	// View and manage your forms in Google Drive
	FormsScope = "https://www.googleapis.com/auth/forms"

	// View and manage forms that this application has been installed in
	FormsCurrentonlyScope = "https://www.googleapis.com/auth/forms.currentonly"

	// View and manage your Google Groups
	GroupsScope = "https://www.googleapis.com/auth/groups"

	// Create and update Google Apps Script deployments
	ScriptDeploymentsScope = "https://www.googleapis.com/auth/script.deployments"

	// View Google Apps Script deployments
	ScriptDeploymentsReadonlyScope = "https://www.googleapis.com/auth/script.deployments.readonly"

	// View Google Apps Script project's metrics
	ScriptMetricsScope = "https://www.googleapis.com/auth/script.metrics"

	// View Google Apps Script processes
	ScriptProcessesScope = "https://www.googleapis.com/auth/script.processes"

	// Create and update Google Apps Script projects
	ScriptProjectsScope = "https://www.googleapis.com/auth/script.projects"

	// View Google Apps Script projects
	ScriptProjectsReadonlyScope = "https://www.googleapis.com/auth/script.projects.readonly"

	// See, edit, create, and delete your spreadsheets in Google Drive
	SpreadsheetsScope = "https://www.googleapis.com/auth/spreadsheets"

	// View your email address
	UserinfoEmailScope = "https://www.googleapis.com/auth/userinfo.email"
)

// NewService creates a new Service.
func NewService(ctx context.Context, opts ...option.ClientOption) (*Service, error) {
	scopesOption := option.WithScopes(
		"https://mail.google.com/",
		"https://www.google.com/calendar/feeds",
		"https://www.google.com/m8/feeds",
		"https://www.googleapis.com/auth/admin.directory.group",
		"https://www.googleapis.com/auth/admin.directory.user",
		"https://www.googleapis.com/auth/documents",
		"https://www.googleapis.com/auth/drive",
		"https://www.googleapis.com/auth/forms",
		"https://www.googleapis.com/auth/forms.currentonly",
		"https://www.googleapis.com/auth/groups",
		"https://www.googleapis.com/auth/script.deployments",
		"https://www.googleapis.com/auth/script.deployments.readonly",
		"https://www.googleapis.com/auth/script.metrics",
		"https://www.googleapis.com/auth/script.processes",
		"https://www.googleapis.com/auth/script.projects",
		"https://www.googleapis.com/auth/script.projects.readonly",
		"https://www.googleapis.com/auth/spreadsheets",
		"https://www.googleapis.com/auth/userinfo.email",
	)
	// NOTE: prepend, so we don't override user-specified scopes.
	opts = append([]option.ClientOption{scopesOption}, opts...)
	opts = append(opts, internaloption.WithDefaultEndpoint(basePath))
	client, endpoint, err := htransport.NewClient(ctx, opts...)
	if err != nil {
		return nil, err
	}
	s, err := New(client)
	if err != nil {
		return nil, err
	}
	if endpoint != "" {
		s.BasePath = endpoint
	}
	return s, nil
}

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

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

	Processes *ProcessesService

	Projects *ProjectsService

	Scripts *ScriptsService
}

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

func NewProcessesService(s *Service) *ProcessesService {
	rs := &ProcessesService{s: s}
	return rs
}

type ProcessesService struct {
	s *Service
}

func NewProjectsService(s *Service) *ProjectsService {
	rs := &ProjectsService{s: s}
	rs.Deployments = NewProjectsDeploymentsService(s)
	rs.Versions = NewProjectsVersionsService(s)
	return rs
}

type ProjectsService struct {
	s *Service

	Deployments *ProjectsDeploymentsService

	Versions *ProjectsVersionsService
}

func NewProjectsDeploymentsService(s *Service) *ProjectsDeploymentsService {
	rs := &ProjectsDeploymentsService{s: s}
	return rs
}

type ProjectsDeploymentsService struct {
	s *Service
}

func NewProjectsVersionsService(s *Service) *ProjectsVersionsService {
	rs := &ProjectsVersionsService{s: s}
	return rs
}

type ProjectsVersionsService struct {
	s *Service
}

func NewScriptsService(s *Service) *ScriptsService {
	rs := &ScriptsService{s: s}
	return rs
}

type ScriptsService struct {
	s *Service
}

// Content: The Content resource.
type Content struct {
	// Files: The list of script project files.
	// One of the files is a script manifest; it must be named
	// "appsscript",
	// must have type of JSON, and include the manifest configurations for
	// the
	// project.
	Files []*File `json:"files,omitempty"`

	// ScriptId: The script project's Drive ID.
	ScriptId string `json:"scriptId,omitempty"`

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

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

// CreateProjectRequest: Request to create a script project.
type CreateProjectRequest struct {
	// ParentId: The Drive ID of a parent file that the created script
	// project is bound to.
	// This is usually the ID of a Google Doc, Google Sheet, Google Form,
	// or
	// Google Slides file. If not set, a standalone script project is
	// created.
	ParentId string `json:"parentId,omitempty"`

	// Title: The title for the project.
	Title string `json:"title,omitempty"`

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

// Deployment: Representation of a single script deployment.
type Deployment struct {
	// DeploymentConfig: The deployment configuration.
	DeploymentConfig *DeploymentConfig `json:"deploymentConfig,omitempty"`

	// DeploymentId: The deployment ID for this deployment.
	DeploymentId string `json:"deploymentId,omitempty"`

	// EntryPoints: The deployment's entry points.
	EntryPoints []*EntryPoint `json:"entryPoints,omitempty"`

	// UpdateTime: Last modified date time stamp.
	UpdateTime string `json:"updateTime,omitempty"`

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

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

// DeploymentConfig: Metadata the defines how a deployment is
// configured.
type DeploymentConfig struct {
	// Description: The description for this deployment.
	Description string `json:"description,omitempty"`

	// ManifestFileName: The manifest file name for this deployment.
	ManifestFileName string `json:"manifestFileName,omitempty"`

	// ScriptId: The script project's Drive ID.
	ScriptId string `json:"scriptId,omitempty"`

	// VersionNumber: The version number on which this deployment is based.
	VersionNumber int64 `json:"versionNumber,omitempty"`

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

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

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

// EntryPoint: A configuration that defines how a deployment is accessed
// externally.
type EntryPoint struct {
	// AddOn: Add-on properties.
	AddOn *GoogleAppsScriptTypeAddOnEntryPoint `json:"addOn,omitempty"`

	// EntryPointType: The type of the entry point.
	//
	// Possible values:
	//   "ENTRY_POINT_TYPE_UNSPECIFIED" - An unspecified entry point.
	//   "WEB_APP" - A web application entry point.
	//   "EXECUTION_API" - An API executable entry point.
	//   "ADD_ON" - An Add-On entry point.
	EntryPointType string `json:"entryPointType,omitempty"`

	// ExecutionApi: An entry point specification for Apps Script API
	// execution calls.
	ExecutionApi *GoogleAppsScriptTypeExecutionApiEntryPoint `json:"executionApi,omitempty"`

	// WebApp: An entry point specification for web apps.
	WebApp *GoogleAppsScriptTypeWebAppEntryPoint `json:"webApp,omitempty"`

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

// ExecuteStreamResponse: The response for executing or debugging a
// function in an Apps Script project.
type ExecuteStreamResponse struct {
	// Result: The result of the execution.
	Result *ScriptExecutionResult `json:"result,omitempty"`

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

// ExecutionError: An object that provides information about the nature
// of an error resulting
// from an attempted execution of a script function using the Apps
// Script API.
// If a run call
// succeeds but the script function (or Apps Script itself) throws an
// exception,
// the response body's error field
// contains a
// Status object. The `Status` object's `details` field
// contains an array with a single one of these `ExecutionError`
// objects.
type ExecutionError struct {
	// ErrorMessage: The error message thrown by Apps Script, usually
	// localized into the user's
	// language.
	ErrorMessage string `json:"errorMessage,omitempty"`

	// ErrorType: The error type, for example `TypeError` or
	// `ReferenceError`. If the error
	// type is unavailable, this field is not included.
	ErrorType string `json:"errorType,omitempty"`

	// ScriptStackTraceElements: An array of objects that provide a stack
	// trace through the script to show
	// where the execution failed, with the deepest call first.
	ScriptStackTraceElements []*ScriptStackTraceElement `json:"scriptStackTraceElements,omitempty"`

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

// ExecutionRequest: A request to run the function in a script. The
// script is identified by the
// specified `script_id`. Executing a function on a script returns
// results
// based on the implementation of the script.
type ExecutionRequest struct {
	// DevMode: If `true` and the user is an owner of the script, the script
	// runs at the
	// most recently saved version rather than the version deployed for use
	// with
	// the Apps Script API. Optional; default is `false`.
	DevMode bool `json:"devMode,omitempty"`

	// Function: The name of the function to execute in the given script.
	// The name does not
	// include parentheses or parameters. It can reference a function in
	// an
	// included library such as `Library.libFunction1`.
	Function string `json:"function,omitempty"`

	// Parameters: The parameters to be passed to the function being
	// executed. The object type
	// for each parameter should match the expected type in Apps
	// Script.
	// Parameters cannot be Apps Script-specific object types (such as
	// a
	// `Document` or a `Calendar`); they can only be primitive types such
	// as
	// `string`, `number`, `array`, `object`, or `boolean`. Optional.
	Parameters []interface{} `json:"parameters,omitempty"`

	// SessionState: <b>Deprecated</b>. For use with Android add-ons only.
	// An ID that represents
	// the user's current session in the Android app for Google Docs or
	// Sheets,
	// included as extra data in
	// the
	// [Intent](https://developer.android.com/guide/components/intents-fi
	// lters.html)
	// that launches the add-on. When an Android add-on is run with a
	// session
	// state, it gains the privileges of
	// a
	// [bound](https://developers.google.com/apps-script/guides/bound)
	// scri
	// pt&mdash;that is, it can access information like the user's
	// current
	// cursor position (in Docs) or selected cell (in Sheets). To retrieve
	// the
	// state,
	// call
	// `Intent.getStringExtra("com.google.android.apps.docs.addons.Sessi
	// onState")`.
	// Optional.
	SessionState string `json:"sessionState,omitempty"`

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

// ExecutionResponse: An object that provides the return value of a
// function executed using the
// Apps Script API. If the script function returns successfully, the
// response
// body's response field contains this
// `ExecutionResponse` object.
type ExecutionResponse struct {
	// Result: The return value of the script function. The type matches the
	// object type
	// returned in Apps Script. Functions called using the Apps Script API
	// cannot
	// return Apps Script-specific objects (such as a `Document` or a
	// `Calendar`);
	// they can only return primitive types such as a `string`, `number`,
	// `array`,
	// `object`, or `boolean`.
	Result interface{} `json:"result,omitempty"`

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

// File: An individual file within a script project.
// A file is a third-party source code created by one or
// more
// developers. It can be a server-side JS code, HTML, or a
// configuration file. Each script project can contain multiple files.
type File struct {
	// CreateTime: Creation date timestamp.
	// This read-only field is only visible to users who have
	// WRITER
	// permission for the script project.
	CreateTime string `json:"createTime,omitempty"`

	// FunctionSet: The defined set of functions in the script file, if any.
	FunctionSet *GoogleAppsScriptTypeFunctionSet `json:"functionSet,omitempty"`

	// LastModifyUser: The user who modified the file most recently.
	// This read-only field is only visible to users who have
	// WRITER
	// permission for the script project.
	LastModifyUser *GoogleAppsScriptTypeUser `json:"lastModifyUser,omitempty"`

	// Name: The name of the file. The file extension is not part of the
	// file
	// name, which can be identified from the type field.
	Name string `json:"name,omitempty"`

	// Source: The file content.
	Source string `json:"source,omitempty"`

	// Type: The type of the file.
	//
	// Possible values:
	//   "ENUM_TYPE_UNSPECIFIED" - Undetermined file type; never actually
	// used.
	//   "SERVER_JS" - An Apps Script server-side code file.
	//   "HTML" - A file containing client-side HTML.
	//   "JSON" - A file in JSON format. This type is only used for the
	// script
	// project's manifest. The manifest file content must match
	// the
	// structure of a
	// valid
	// [ScriptManifest](/apps-script/concepts/manifests)
	Type string `json:"type,omitempty"`

	// UpdateTime: Last modified date timestamp.
	// This read-only field is only visible to users who have
	// WRITER
	// permission for the script project.
	UpdateTime string `json:"updateTime,omitempty"`

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

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

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

// GoogleAppsScriptTypeAddOnEntryPoint: An add-on entry point.
type GoogleAppsScriptTypeAddOnEntryPoint struct {
	// AddOnType: The add-on's required list of supported container types.
	//
	// Possible values:
	//   "UNKNOWN_ADDON_TYPE" - Default value, unknown add-on type.
	//   "GMAIL" - Add-on type for Gmail.
	//   "DATA_STUDIO" - Add-on type for Data Studio.
	AddOnType string `json:"addOnType,omitempty"`

	// Description: The add-on's optional description.
	Description string `json:"description,omitempty"`

	// HelpUrl: The add-on's optional help URL.
	HelpUrl string `json:"helpUrl,omitempty"`

	// PostInstallTipUrl: The add-on's required post install tip URL.
	PostInstallTipUrl string `json:"postInstallTipUrl,omitempty"`

	// ReportIssueUrl: The add-on's optional report issue URL.
	ReportIssueUrl string `json:"reportIssueUrl,omitempty"`

	// Title: The add-on's required title.
	Title string `json:"title,omitempty"`

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

// GoogleAppsScriptTypeExecutionApiConfig: API executable entry point
// configuration.
type GoogleAppsScriptTypeExecutionApiConfig struct {
	// Access: Who has permission to run the API executable.
	//
	// Possible values:
	//   "UNKNOWN_ACCESS" - Default value, should not be used.
	//   "MYSELF" - Only the user who deployed the web app or executable can
	// access it.
	// Note that this is not necessarily the owner of the script project.
	//   "DOMAIN" - Only users in the same domain as the user who deployed
	// the web app or
	// executable can access it.
	//   "ANYONE" - Any logged in user can access the web app or executable.
	//   "ANYONE_ANONYMOUS" - Any user, logged in or not, can access the web
	// app or executable.
	Access string `json:"access,omitempty"`

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

// GoogleAppsScriptTypeExecutionApiEntryPoint: An API executable entry
// point.
type GoogleAppsScriptTypeExecutionApiEntryPoint struct {
	// EntryPointConfig: The entry point's configuration.
	EntryPointConfig *GoogleAppsScriptTypeExecutionApiConfig `json:"entryPointConfig,omitempty"`

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

// GoogleAppsScriptTypeFunction: Represents a function in a script
// project.
type GoogleAppsScriptTypeFunction struct {
	// Name: The function name in the script project.
	Name string `json:"name,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 *GoogleAppsScriptTypeFunction) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleAppsScriptTypeFunction
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleAppsScriptTypeFunctionSet: A set of functions. No duplicates
// are permitted.
type GoogleAppsScriptTypeFunctionSet struct {
	// Values: A list of functions composing the set.
	Values []*GoogleAppsScriptTypeFunction `json:"values,omitempty"`

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

// GoogleAppsScriptTypeProcess: Representation of a single script
// process execution that was started from
// the script editor, a trigger, an application, or using the Apps
// Script API.
// This is distinct from the `Operation`
// resource, which only represents executions started via the Apps
// Script API.
type GoogleAppsScriptTypeProcess struct {
	// Duration: Duration the execution spent executing.
	Duration string `json:"duration,omitempty"`

	// FunctionName: Name of the function the started the execution.
	FunctionName string `json:"functionName,omitempty"`

	// ProcessStatus: The executions status.
	//
	// Possible values:
	//   "PROCESS_STATUS_UNSPECIFIED" - Unspecified status.
	//   "RUNNING" - The process is currently running.
	//   "PAUSED" - The process has paused.
	//   "COMPLETED" - The process has completed.
	//   "CANCELED" - The process was cancelled.
	//   "FAILED" - The process failed.
	//   "TIMED_OUT" - The process timed out.
	//   "UNKNOWN" - Process status unknown.
	//   "DELAYED" - The process is delayed, waiting for quota.
	ProcessStatus string `json:"processStatus,omitempty"`

	// ProcessType: The executions type.
	//
	// Possible values:
	//   "PROCESS_TYPE_UNSPECIFIED" - Unspecified type.
	//   "ADD_ON" - The process was started from an add-on entry point.
	//   "EXECUTION_API" - The process was started using the Apps Script
	// API.
	//   "TIME_DRIVEN" - The process was started from a time-based trigger.
	//   "TRIGGER" - The process was started from an event-based trigger.
	//   "WEBAPP" - The process was started from a web app entry point.
	//   "EDITOR" - The process was started using the Apps Script IDE.
	//   "SIMPLE_TRIGGER" - The process was started from a G Suite simple
	// trigger.
	//   "MENU" - The process was started from a G Suite menu item.
	//   "BATCH_TASK" - The process was started as a task in a batch job.
	ProcessType string `json:"processType,omitempty"`

	// ProjectName: Name of the script being executed.
	ProjectName string `json:"projectName,omitempty"`

	// StartTime: Time the execution started.
	StartTime string `json:"startTime,omitempty"`

	// UserAccessLevel: The executing users access level to the script.
	//
	// Possible values:
	//   "USER_ACCESS_LEVEL_UNSPECIFIED" - User access level unspecified
	//   "NONE" - The user has no access.
	//   "READ" - The user has read-only access.
	//   "WRITE" - The user has write access.
	//   "OWNER" - The user is an owner.
	UserAccessLevel string `json:"userAccessLevel,omitempty"`

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

// GoogleAppsScriptTypeUser: A simple user profile resource.
type GoogleAppsScriptTypeUser struct {
	// Domain: The user's domain.
	Domain string `json:"domain,omitempty"`

	// Email: The user's identifying email address.
	Email string `json:"email,omitempty"`

	// Name: The user's display name.
	Name string `json:"name,omitempty"`

	// PhotoUrl: The user's photo.
	PhotoUrl string `json:"photoUrl,omitempty"`

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

// GoogleAppsScriptTypeWebAppConfig: Web app entry point configuration.
type GoogleAppsScriptTypeWebAppConfig struct {
	// Access: Who has permission to run the web app.
	//
	// Possible values:
	//   "UNKNOWN_ACCESS" - Default value, should not be used.
	//   "MYSELF" - Only the user who deployed the web app or executable can
	// access it.
	// Note that this is not necessarily the owner of the script project.
	//   "DOMAIN" - Only users in the same domain as the user who deployed
	// the web app or
	// executable can access it.
	//   "ANYONE" - Any logged in user can access the web app or executable.
	//   "ANYONE_ANONYMOUS" - Any user, logged in or not, can access the web
	// app or executable.
	Access string `json:"access,omitempty"`

	// ExecuteAs: Who to execute the web app as.
	//
	// Possible values:
	//   "UNKNOWN_EXECUTE_AS" - Default value, should not be used.
	//   "USER_ACCESSING" - The script runs as the user accessing the web
	// app.
	//   "USER_DEPLOYING" - The script runs as the user who deployed the web
	// app. Note that this is
	// not necessarily the owner of the script project.
	ExecuteAs string `json:"executeAs,omitempty"`

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

// GoogleAppsScriptTypeWebAppEntryPoint: A web application entry point.
type GoogleAppsScriptTypeWebAppEntryPoint struct {
	// EntryPointConfig: The entry point's configuration.
	EntryPointConfig *GoogleAppsScriptTypeWebAppConfig `json:"entryPointConfig,omitempty"`

	// Url: The URL for the web application.
	Url string `json:"url,omitempty"`

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

// ListDeploymentsResponse: Response with the list of deployments for
// the specified Apps Script project.
type ListDeploymentsResponse struct {
	// Deployments: The list of deployments.
	Deployments []*Deployment `json:"deployments,omitempty"`

	// NextPageToken: The token that can be used in the next call to get the
	// next page of
	// results.
	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. "Deployments") 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. "Deployments") 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 *ListDeploymentsResponse) MarshalJSON() ([]byte, error) {
	type NoMethod ListDeploymentsResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ListScriptProcessesResponse: Response with the list of
// Process resources.
type ListScriptProcessesResponse struct {
	// NextPageToken: Token for the next page of results. If empty, there
	// are no more pages
	// remaining.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// Processes: List of processes matching request parameters.
	Processes []*GoogleAppsScriptTypeProcess `json:"processes,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 *ListScriptProcessesResponse) MarshalJSON() ([]byte, error) {
	type NoMethod ListScriptProcessesResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ListUserProcessesResponse: Response with the list of
// Process resources.
type ListUserProcessesResponse struct {
	// NextPageToken: Token for the next page of results. If empty, there
	// are no more pages
	// remaining.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// Processes: List of processes matching request parameters.
	Processes []*GoogleAppsScriptTypeProcess `json:"processes,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 *ListUserProcessesResponse) MarshalJSON() ([]byte, error) {
	type NoMethod ListUserProcessesResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ListValue: `ListValue` is a wrapper around a repeated field of
// values.
type ListValue struct {
	// Values: Repeated field of dynamically typed values.
	Values []*Value `json:"values,omitempty"`

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

// ListVersionsResponse: Response with the list of the versions for the
// specified script project.
type ListVersionsResponse struct {
	// NextPageToken: The token use to fetch the next page of records. if
	// not exist in the
	// response, that means no more versions to list.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// Versions: The list of versions.
	Versions []*Version `json:"versions,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 *ListVersionsResponse) MarshalJSON() ([]byte, error) {
	type NoMethod ListVersionsResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Metrics: Resource containing usage stats for a given script, based on
// the supplied
// filter and mask present in the request.
type Metrics struct {
	// ActiveUsers: Number of active users.
	ActiveUsers []*MetricsValue `json:"activeUsers,omitempty"`

	// FailedExecutions: Number of failed executions.
	FailedExecutions []*MetricsValue `json:"failedExecutions,omitempty"`

	// TotalExecutions: Number of total executions.
	TotalExecutions []*MetricsValue `json:"totalExecutions,omitempty"`

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

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

// MetricsValue: Metrics value that holds number of executions counted.
type MetricsValue struct {
	// EndTime: Required field indicating the end time of the interval.
	EndTime string `json:"endTime,omitempty"`

	// StartTime: Required field indicating the start time of the interval.
	StartTime string `json:"startTime,omitempty"`

	// Value: Indicates the number of executions counted.
	Value uint64 `json:"value,omitempty,string"`

	// 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 *MetricsValue) MarshalJSON() ([]byte, error) {
	type NoMethod MetricsValue
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Operation: A representation of an execution of an Apps Script
// function started with run. The execution response does not arrive
// until the function finishes executing. The maximum execution runtime
// is listed in the [Apps Script quotas
// guide](/apps-script/guides/services/quotas#current_limitations).
// <p>After execution has started, it can have one of four outcomes:</p>
// <ul> <li> If the script function returns successfully, the
//   response field contains an
//   ExecutionResponse object
//   with the function's return value in the object's `result`
// field.</li>
// <li> If the script function (or Apps Script itself) throws an
// exception, the
//   error field contains a
//   Status object. The `Status` object's `details`
//   field contains an array with a single
//   ExecutionError object that
//   provides information about the nature of the error.</li>
// <li> If the execution has not yet completed,
//   the done field is `false` and
//   the neither the `response` nor `error` fields are
// present.</li>
// <li> If the `run` call itself fails (for example, because of a
//   malformed request or an authorization error), the method returns an
// HTTP
//   response code in the 4XX range with a different format for the
// response
//   body. Client libraries automatically convert a 4XX response into
// an
//   exception class.</li>
// </ul>
type Operation struct {
	// Done: This field indicates whether the script execution has
	// completed. A completed execution has a populated `response` field
	// containing the ExecutionResponse from function that was executed.
	Done bool `json:"done,omitempty"`

	// Error: If a `run` call succeeds but the script function (or Apps
	// Script itself) throws an exception, this field contains a Status
	// object. The `Status` object's `details` field contains an array with
	// a single ExecutionError object that provides information about the
	// nature of the error.
	Error *Status `json:"error,omitempty"`

	// Response: If the script function returns successfully, this field
	// contains an ExecutionResponse object with the function's return
	// value.
	Response googleapi.RawMessage `json:"response,omitempty"`

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

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

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

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

// Project: The script project resource.
type Project struct {
	// CreateTime: When the script was created.
	CreateTime string `json:"createTime,omitempty"`

	// Creator: User who originally created the script.
	Creator *GoogleAppsScriptTypeUser `json:"creator,omitempty"`

	// LastModifyUser: User who last modified the script.
	LastModifyUser *GoogleAppsScriptTypeUser `json:"lastModifyUser,omitempty"`

	// ParentId: The parent's Drive ID that the script will be attached to.
	// This is usually
	// the ID of a Google Document or Google Sheet. This filed is optional,
	// and
	// if not set, a stand-alone script will be created.
	ParentId string `json:"parentId,omitempty"`

	// ScriptId: The script project's Drive ID.
	ScriptId string `json:"scriptId,omitempty"`

	// Title: The title for the project.
	Title string `json:"title,omitempty"`

	// UpdateTime: When the script was last updated.
	UpdateTime string `json:"updateTime,omitempty"`

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

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

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

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

// ScriptExecutionResult: The result of an execution.
type ScriptExecutionResult struct {
	// ReturnValue: The returned value of the execution.
	ReturnValue *Value `json:"returnValue,omitempty"`

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

// ScriptStackTraceElement: A stack trace through the script that shows
// where the execution failed.
type ScriptStackTraceElement struct {
	// Function: The name of the function that failed.
	Function string `json:"function,omitempty"`

	// LineNumber: The line number where the script failed.
	LineNumber int64 `json:"lineNumber,omitempty"`

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

// Status: If a `run` call succeeds but the script function (or Apps
// Script itself) throws an exception, the response body's error field
// contains this `Status` object.
type Status struct {
	// Code: The status code. For this API, this value either: <ul> <li> 10,
	// indicating a `SCRIPT_TIMEOUT` error,</li> <li> 3, indicating an
	// `INVALID_ARGUMENT` error, or</li> <li> 1, indicating a `CANCELLED`
	// execution.</li> </ul>
	Code int64 `json:"code,omitempty"`

	// Details: An array that contains a single ExecutionError object that
	// provides information about the nature of the error.
	Details []googleapi.RawMessage `json:"details,omitempty"`

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

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

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

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

// Struct: `Struct` represents a structured data value, consisting of
// fields which map
// to dynamically typed values.
type Struct struct {
	// Fields: Unordered map of dynamically typed values.
	Fields map[string]Value `json:"fields,omitempty"`

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

// UpdateDeploymentRequest: Request with deployment information to
// update an existing deployment.
type UpdateDeploymentRequest struct {
	// DeploymentConfig: The deployment configuration.
	DeploymentConfig *DeploymentConfig `json:"deploymentConfig,omitempty"`

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

// Value: `Value` represents a dynamically typed value which is the
// outcome of an
// executed script.
type Value struct {
	// BoolValue: Represents a boolean value.
	BoolValue bool `json:"boolValue,omitempty"`

	// BytesValue: Represents raw byte values.
	BytesValue string `json:"bytesValue,omitempty"`

	// DateValue: Represents a date in ms since the epoch.
	DateValue int64 `json:"dateValue,omitempty,string"`

	// ListValue: Represents a repeated `Value`.
	ListValue *ListValue `json:"listValue,omitempty"`

	// NullValue: Represents a null value.
	//
	// Possible values:
	//   "NULL_VALUE" - Null value.
	NullValue string `json:"nullValue,omitempty"`

	// NumberValue: Represents a double value.
	NumberValue float64 `json:"numberValue,omitempty"`

	// ProtoValue: Represents a structured proto value.
	ProtoValue googleapi.RawMessage `json:"protoValue,omitempty"`

	// StringValue: Represents a string value.
	StringValue string `json:"stringValue,omitempty"`

	// StructValue: Represents a structured value.
	StructValue *Struct `json:"structValue,omitempty"`

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

func (s *Value) UnmarshalJSON(data []byte) error {
	type NoMethod Value
	var s1 struct {
		NumberValue gensupport.JSONFloat64 `json:"numberValue"`
		*NoMethod
	}
	s1.NoMethod = (*NoMethod)(s)
	if err := json.Unmarshal(data, &s1); err != nil {
		return err
	}
	s.NumberValue = float64(s1.NumberValue)
	return nil
}

// Version: A resource representing a script project version. A version
// is a "snapshot"
// of a script project and is similar to a read-only branched release.
// When
// creating deployments, the version to use must be specified.
type Version struct {
	// CreateTime: When the version was created.
	CreateTime string `json:"createTime,omitempty"`

	// Description: The description for this version.
	Description string `json:"description,omitempty"`

	// ScriptId: The script project's Drive ID.
	ScriptId string `json:"scriptId,omitempty"`

	// VersionNumber: The incremental ID that is created by Apps Script when
	// a version is
	// created. This is system assigned number and is immutable once
	// created.
	VersionNumber int64 `json:"versionNumber,omitempty"`

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

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

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

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

// method id "script.processes.list":

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

// List: List information about processes made by or on behalf of a
// user,
// such as process type and current status.
func (r *ProcessesService) List() *ProcessesListCall {
	c := &ProcessesListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	return c
}

// PageSize sets the optional parameter "pageSize": The maximum number
// of returned processes per page of results. Defaults to
// 50.
func (c *ProcessesListCall) PageSize(pageSize int64) *ProcessesListCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": The token for
// continuing a previous list request on the next page. This
// should be set to the value of `nextPageToken` from a previous
// response.
func (c *ProcessesListCall) PageToken(pageToken string) *ProcessesListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// UserProcessFilterDeploymentId sets the optional parameter
// "userProcessFilter.deploymentId": Optional field used to limit
// returned processes to those originating from
// projects with a specific deployment ID.
func (c *ProcessesListCall) UserProcessFilterDeploymentId(userProcessFilterDeploymentId string) *ProcessesListCall {
	c.urlParams_.Set("userProcessFilter.deploymentId", userProcessFilterDeploymentId)
	return c
}

// UserProcessFilterEndTime sets the optional parameter
// "userProcessFilter.endTime": Optional field used to limit returned
// processes to those that completed
// on or before the given timestamp.
func (c *ProcessesListCall) UserProcessFilterEndTime(userProcessFilterEndTime string) *ProcessesListCall {
	c.urlParams_.Set("userProcessFilter.endTime", userProcessFilterEndTime)
	return c
}

// UserProcessFilterFunctionName sets the optional parameter
// "userProcessFilter.functionName": Optional field used to limit
// returned processes to those originating from
// a script function with the given function name.
func (c *ProcessesListCall) UserProcessFilterFunctionName(userProcessFilterFunctionName string) *ProcessesListCall {
	c.urlParams_.Set("userProcessFilter.functionName", userProcessFilterFunctionName)
	return c
}

// UserProcessFilterProjectName sets the optional parameter
// "userProcessFilter.projectName": Optional field used to limit
// returned processes to those originating from
// projects with project names containing a specific string.
func (c *ProcessesListCall) UserProcessFilterProjectName(userProcessFilterProjectName string) *ProcessesListCall {
	c.urlParams_.Set("userProcessFilter.projectName", userProcessFilterProjectName)
	return c
}

// UserProcessFilterScriptId sets the optional parameter
// "userProcessFilter.scriptId": Optional field used to limit returned
// processes to those originating from
// projects with a specific script ID.
func (c *ProcessesListCall) UserProcessFilterScriptId(userProcessFilterScriptId string) *ProcessesListCall {
	c.urlParams_.Set("userProcessFilter.scriptId", userProcessFilterScriptId)
	return c
}

// UserProcessFilterStartTime sets the optional parameter
// "userProcessFilter.startTime": Optional field used to limit returned
// processes to those that were
// started on or after the given timestamp.
func (c *ProcessesListCall) UserProcessFilterStartTime(userProcessFilterStartTime string) *ProcessesListCall {
	c.urlParams_.Set("userProcessFilter.startTime", userProcessFilterStartTime)
	return c
}

// UserProcessFilterStatuses sets the optional parameter
// "userProcessFilter.statuses": Optional field used to limit returned
// processes to those having one of
// the specified process statuses.
//
// Possible values:
//   "PROCESS_STATUS_UNSPECIFIED"
//   "RUNNING"
//   "PAUSED"
//   "COMPLETED"
//   "CANCELED"
//   "FAILED"
//   "TIMED_OUT"
//   "UNKNOWN"
//   "DELAYED"
func (c *ProcessesListCall) UserProcessFilterStatuses(userProcessFilterStatuses ...string) *ProcessesListCall {
	c.urlParams_.SetMulti("userProcessFilter.statuses", append([]string{}, userProcessFilterStatuses...))
	return c
}

// UserProcessFilterTypes sets the optional parameter
// "userProcessFilter.types": Optional field used to limit returned
// processes to those having one of
// the specified process types.
//
// Possible values:
//   "PROCESS_TYPE_UNSPECIFIED"
//   "ADD_ON"
//   "EXECUTION_API"
//   "TIME_DRIVEN"
//   "TRIGGER"
//   "WEBAPP"
//   "EDITOR"
//   "SIMPLE_TRIGGER"
//   "MENU"
//   "BATCH_TASK"
func (c *ProcessesListCall) UserProcessFilterTypes(userProcessFilterTypes ...string) *ProcessesListCall {
	c.urlParams_.SetMulti("userProcessFilter.types", append([]string{}, userProcessFilterTypes...))
	return c
}

// UserProcessFilterUserAccessLevels sets the optional parameter
// "userProcessFilter.userAccessLevels": Optional field used to limit
// returned processes to those having one of
// the specified user access levels.
//
// Possible values:
//   "USER_ACCESS_LEVEL_UNSPECIFIED"
//   "NONE"
//   "READ"
//   "WRITE"
//   "OWNER"
func (c *ProcessesListCall) UserProcessFilterUserAccessLevels(userProcessFilterUserAccessLevels ...string) *ProcessesListCall {
	c.urlParams_.SetMulti("userProcessFilter.userAccessLevels", append([]string{}, userProcessFilterUserAccessLevels...))
	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 *ProcessesListCall) Fields(s ...googleapi.Field) *ProcessesListCall {
	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 *ProcessesListCall) IfNoneMatch(entityTag string) *ProcessesListCall {
	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 *ProcessesListCall) Context(ctx context.Context) *ProcessesListCall {
	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 *ProcessesListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProcessesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200501")
	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/processes")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "script.processes.list" call.
// Exactly one of *ListUserProcessesResponse or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *ListUserProcessesResponse.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 *ProcessesListCall) Do(opts ...googleapi.CallOption) (*ListUserProcessesResponse, 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 := &ListUserProcessesResponse{
		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 information about processes made by or on behalf of a user,\nsuch as process type and current status.",
	//   "flatPath": "v1/processes",
	//   "httpMethod": "GET",
	//   "id": "script.processes.list",
	//   "parameterOrder": [],
	//   "parameters": {
	//     "pageSize": {
	//       "description": "The maximum number of returned processes per page of results. Defaults to\n50.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "The token for continuing a previous list request on the next page. This\nshould be set to the value of `nextPageToken` from a previous response.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "userProcessFilter.deploymentId": {
	//       "description": "Optional field used to limit returned processes to those originating from\nprojects with a specific deployment ID.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "userProcessFilter.endTime": {
	//       "description": "Optional field used to limit returned processes to those that completed\non or before the given timestamp.",
	//       "format": "google-datetime",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "userProcessFilter.functionName": {
	//       "description": "Optional field used to limit returned processes to those originating from\na script function with the given function name.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "userProcessFilter.projectName": {
	//       "description": "Optional field used to limit returned processes to those originating from\nprojects with project names containing a specific string.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "userProcessFilter.scriptId": {
	//       "description": "Optional field used to limit returned processes to those originating from\nprojects with a specific script ID.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "userProcessFilter.startTime": {
	//       "description": "Optional field used to limit returned processes to those that were\nstarted on or after the given timestamp.",
	//       "format": "google-datetime",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "userProcessFilter.statuses": {
	//       "description": "Optional field used to limit returned processes to those having one of\nthe specified process statuses.",
	//       "enum": [
	//         "PROCESS_STATUS_UNSPECIFIED",
	//         "RUNNING",
	//         "PAUSED",
	//         "COMPLETED",
	//         "CANCELED",
	//         "FAILED",
	//         "TIMED_OUT",
	//         "UNKNOWN",
	//         "DELAYED"
	//       ],
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "userProcessFilter.types": {
	//       "description": "Optional field used to limit returned processes to those having one of\nthe specified process types.",
	//       "enum": [
	//         "PROCESS_TYPE_UNSPECIFIED",
	//         "ADD_ON",
	//         "EXECUTION_API",
	//         "TIME_DRIVEN",
	//         "TRIGGER",
	//         "WEBAPP",
	//         "EDITOR",
	//         "SIMPLE_TRIGGER",
	//         "MENU",
	//         "BATCH_TASK"
	//       ],
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "userProcessFilter.userAccessLevels": {
	//       "description": "Optional field used to limit returned processes to those having one of\nthe specified user access levels.",
	//       "enum": [
	//         "USER_ACCESS_LEVEL_UNSPECIFIED",
	//         "NONE",
	//         "READ",
	//         "WRITE",
	//         "OWNER"
	//       ],
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/processes",
	//   "response": {
	//     "$ref": "ListUserProcessesResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/script.processes"
	//   ]
	// }

}

// 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 *ProcessesListCall) Pages(ctx context.Context, f func(*ListUserProcessesResponse) 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 "script.processes.listScriptProcesses":

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

// ListScriptProcesses: List information about a script's executed
// processes, such as process type
// and current status.
func (r *ProcessesService) ListScriptProcesses() *ProcessesListScriptProcessesCall {
	c := &ProcessesListScriptProcessesCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	return c
}

// PageSize sets the optional parameter "pageSize": The maximum number
// of returned processes per page of results. Defaults to
// 50.
func (c *ProcessesListScriptProcessesCall) PageSize(pageSize int64) *ProcessesListScriptProcessesCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": The token for
// continuing a previous list request on the next page. This
// should be set to the value of `nextPageToken` from a previous
// response.
func (c *ProcessesListScriptProcessesCall) PageToken(pageToken string) *ProcessesListScriptProcessesCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// ScriptId sets the optional parameter "scriptId": The script ID of the
// project whose processes are listed.
func (c *ProcessesListScriptProcessesCall) ScriptId(scriptId string) *ProcessesListScriptProcessesCall {
	c.urlParams_.Set("scriptId", scriptId)
	return c
}

// ScriptProcessFilterDeploymentId sets the optional parameter
// "scriptProcessFilter.deploymentId": Optional field used to limit
// returned processes to those originating from
// projects with a specific deployment ID.
func (c *ProcessesListScriptProcessesCall) ScriptProcessFilterDeploymentId(scriptProcessFilterDeploymentId string) *ProcessesListScriptProcessesCall {
	c.urlParams_.Set("scriptProcessFilter.deploymentId", scriptProcessFilterDeploymentId)
	return c
}

// ScriptProcessFilterEndTime sets the optional parameter
// "scriptProcessFilter.endTime": Optional field used to limit returned
// processes to those that completed
// on or before the given timestamp.
func (c *ProcessesListScriptProcessesCall) ScriptProcessFilterEndTime(scriptProcessFilterEndTime string) *ProcessesListScriptProcessesCall {
	c.urlParams_.Set("scriptProcessFilter.endTime", scriptProcessFilterEndTime)
	return c
}

// ScriptProcessFilterFunctionName sets the optional parameter
// "scriptProcessFilter.functionName": Optional field used to limit
// returned processes to those originating from
// a script function with the given function name.
func (c *ProcessesListScriptProcessesCall) ScriptProcessFilterFunctionName(scriptProcessFilterFunctionName string) *ProcessesListScriptProcessesCall {
	c.urlParams_.Set("scriptProcessFilter.functionName", scriptProcessFilterFunctionName)
	return c
}

// ScriptProcessFilterStartTime sets the optional parameter
// "scriptProcessFilter.startTime": Optional field used to limit
// returned processes to those that were
// started on or after the given timestamp.
func (c *ProcessesListScriptProcessesCall) ScriptProcessFilterStartTime(scriptProcessFilterStartTime string) *ProcessesListScriptProcessesCall {
	c.urlParams_.Set("scriptProcessFilter.startTime", scriptProcessFilterStartTime)
	return c
}

// ScriptProcessFilterStatuses sets the optional parameter
// "scriptProcessFilter.statuses": Optional field used to limit returned
// processes to those having one of
// the specified process statuses.
//
// Possible values:
//   "PROCESS_STATUS_UNSPECIFIED"
//   "RUNNING"
//   "PAUSED"
//   "COMPLETED"
//   "CANCELED"
//   "FAILED"
//   "TIMED_OUT"
//   "UNKNOWN"
//   "DELAYED"
func (c *ProcessesListScriptProcessesCall) ScriptProcessFilterStatuses(scriptProcessFilterStatuses ...string) *ProcessesListScriptProcessesCall {
	c.urlParams_.SetMulti("scriptProcessFilter.statuses", append([]string{}, scriptProcessFilterStatuses...))
	return c
}

// ScriptProcessFilterTypes sets the optional parameter
// "scriptProcessFilter.types": Optional field used to limit returned
// processes to those having one of
// the specified process types.
//
// Possible values:
//   "PROCESS_TYPE_UNSPECIFIED"
//   "ADD_ON"
//   "EXECUTION_API"
//   "TIME_DRIVEN"
//   "TRIGGER"
//   "WEBAPP"
//   "EDITOR"
//   "SIMPLE_TRIGGER"
//   "MENU"
//   "BATCH_TASK"
func (c *ProcessesListScriptProcessesCall) ScriptProcessFilterTypes(scriptProcessFilterTypes ...string) *ProcessesListScriptProcessesCall {
	c.urlParams_.SetMulti("scriptProcessFilter.types", append([]string{}, scriptProcessFilterTypes...))
	return c
}

// ScriptProcessFilterUserAccessLevels sets the optional parameter
// "scriptProcessFilter.userAccessLevels": Optional field used to limit
// returned processes to those having one of
// the specified user access levels.
//
// Possible values:
//   "USER_ACCESS_LEVEL_UNSPECIFIED"
//   "NONE"
//   "READ"
//   "WRITE"
//   "OWNER"
func (c *ProcessesListScriptProcessesCall) ScriptProcessFilterUserAccessLevels(scriptProcessFilterUserAccessLevels ...string) *ProcessesListScriptProcessesCall {
	c.urlParams_.SetMulti("scriptProcessFilter.userAccessLevels", append([]string{}, scriptProcessFilterUserAccessLevels...))
	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 *ProcessesListScriptProcessesCall) Fields(s ...googleapi.Field) *ProcessesListScriptProcessesCall {
	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 *ProcessesListScriptProcessesCall) IfNoneMatch(entityTag string) *ProcessesListScriptProcessesCall {
	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 *ProcessesListScriptProcessesCall) Context(ctx context.Context) *ProcessesListScriptProcessesCall {
	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 *ProcessesListScriptProcessesCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProcessesListScriptProcessesCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200501")
	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/processes:listScriptProcesses")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "script.processes.listScriptProcesses" call.
// Exactly one of *ListScriptProcessesResponse or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *ListScriptProcessesResponse.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 *ProcessesListScriptProcessesCall) Do(opts ...googleapi.CallOption) (*ListScriptProcessesResponse, 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 := &ListScriptProcessesResponse{
		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 information about a script's executed processes, such as process type\nand current status.",
	//   "flatPath": "v1/processes:listScriptProcesses",
	//   "httpMethod": "GET",
	//   "id": "script.processes.listScriptProcesses",
	//   "parameterOrder": [],
	//   "parameters": {
	//     "pageSize": {
	//       "description": "The maximum number of returned processes per page of results. Defaults to\n50.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "The token for continuing a previous list request on the next page. This\nshould be set to the value of `nextPageToken` from a previous response.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "scriptId": {
	//       "description": "The script ID of the project whose processes are listed.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "scriptProcessFilter.deploymentId": {
	//       "description": "Optional field used to limit returned processes to those originating from\nprojects with a specific deployment ID.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "scriptProcessFilter.endTime": {
	//       "description": "Optional field used to limit returned processes to those that completed\non or before the given timestamp.",
	//       "format": "google-datetime",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "scriptProcessFilter.functionName": {
	//       "description": "Optional field used to limit returned processes to those originating from\na script function with the given function name.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "scriptProcessFilter.startTime": {
	//       "description": "Optional field used to limit returned processes to those that were\nstarted on or after the given timestamp.",
	//       "format": "google-datetime",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "scriptProcessFilter.statuses": {
	//       "description": "Optional field used to limit returned processes to those having one of\nthe specified process statuses.",
	//       "enum": [
	//         "PROCESS_STATUS_UNSPECIFIED",
	//         "RUNNING",
	//         "PAUSED",
	//         "COMPLETED",
	//         "CANCELED",
	//         "FAILED",
	//         "TIMED_OUT",
	//         "UNKNOWN",
	//         "DELAYED"
	//       ],
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "scriptProcessFilter.types": {
	//       "description": "Optional field used to limit returned processes to those having one of\nthe specified process types.",
	//       "enum": [
	//         "PROCESS_TYPE_UNSPECIFIED",
	//         "ADD_ON",
	//         "EXECUTION_API",
	//         "TIME_DRIVEN",
	//         "TRIGGER",
	//         "WEBAPP",
	//         "EDITOR",
	//         "SIMPLE_TRIGGER",
	//         "MENU",
	//         "BATCH_TASK"
	//       ],
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "scriptProcessFilter.userAccessLevels": {
	//       "description": "Optional field used to limit returned processes to those having one of\nthe specified user access levels.",
	//       "enum": [
	//         "USER_ACCESS_LEVEL_UNSPECIFIED",
	//         "NONE",
	//         "READ",
	//         "WRITE",
	//         "OWNER"
	//       ],
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/processes:listScriptProcesses",
	//   "response": {
	//     "$ref": "ListScriptProcessesResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/script.processes"
	//   ]
	// }

}

// 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 *ProcessesListScriptProcessesCall) Pages(ctx context.Context, f func(*ListScriptProcessesResponse) 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 "script.projects.create":

type ProjectsCreateCall struct {
	s                    *Service
	createprojectrequest *CreateProjectRequest
	urlParams_           gensupport.URLParams
	ctx_                 context.Context
	header_              http.Header
}

// Create: Creates a new, empty script project with no script files and
// a base
// manifest file.
func (r *ProjectsService) Create(createprojectrequest *CreateProjectRequest) *ProjectsCreateCall {
	c := &ProjectsCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.createprojectrequest = createprojectrequest
	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 *ProjectsCreateCall) Fields(s ...googleapi.Field) *ProjectsCreateCall {
	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 *ProjectsCreateCall) Context(ctx context.Context) *ProjectsCreateCall {
	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 *ProjectsCreateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsCreateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200501")
	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.createprojectrequest)
	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/projects")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "script.projects.create" call.
// Exactly one of *Project or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Project.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 *ProjectsCreateCall) Do(opts ...googleapi.CallOption) (*Project, 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 := &Project{
		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, empty script project with no script files and a base\nmanifest file.",
	//   "flatPath": "v1/projects",
	//   "httpMethod": "POST",
	//   "id": "script.projects.create",
	//   "parameterOrder": [],
	//   "parameters": {},
	//   "path": "v1/projects",
	//   "request": {
	//     "$ref": "CreateProjectRequest"
	//   },
	//   "response": {
	//     "$ref": "Project"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/script.projects"
	//   ]
	// }

}

// method id "script.projects.get":

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

// Get: Gets a script project's metadata.
func (r *ProjectsService) Get(scriptId string) *ProjectsGetCall {
	c := &ProjectsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.scriptId = scriptId
	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 *ProjectsGetCall) Fields(s ...googleapi.Field) *ProjectsGetCall {
	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 *ProjectsGetCall) IfNoneMatch(entityTag string) *ProjectsGetCall {
	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 *ProjectsGetCall) Context(ctx context.Context) *ProjectsGetCall {
	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 *ProjectsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200501")
	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/projects/{scriptId}")
	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{
		"scriptId": c.scriptId,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "script.projects.get" call.
// Exactly one of *Project or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Project.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 *ProjectsGetCall) Do(opts ...googleapi.CallOption) (*Project, 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 := &Project{
		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 script project's metadata.",
	//   "flatPath": "v1/projects/{scriptId}",
	//   "httpMethod": "GET",
	//   "id": "script.projects.get",
	//   "parameterOrder": [
	//     "scriptId"
	//   ],
	//   "parameters": {
	//     "scriptId": {
	//       "description": "The script project's Drive ID.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/projects/{scriptId}",
	//   "response": {
	//     "$ref": "Project"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/script.projects",
	//     "https://www.googleapis.com/auth/script.projects.readonly"
	//   ]
	// }

}

// method id "script.projects.getContent":

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

// GetContent: Gets the content of the script project, including the
// code source and
// metadata for each script file.
func (r *ProjectsService) GetContent(scriptId string) *ProjectsGetContentCall {
	c := &ProjectsGetContentCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.scriptId = scriptId
	return c
}

// VersionNumber sets the optional parameter "versionNumber": The
// version number of the project to retrieve. If not provided,
// the
// project's HEAD version is returned.
func (c *ProjectsGetContentCall) VersionNumber(versionNumber int64) *ProjectsGetContentCall {
	c.urlParams_.Set("versionNumber", fmt.Sprint(versionNumber))
	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 *ProjectsGetContentCall) Fields(s ...googleapi.Field) *ProjectsGetContentCall {
	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 *ProjectsGetContentCall) IfNoneMatch(entityTag string) *ProjectsGetContentCall {
	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 *ProjectsGetContentCall) Context(ctx context.Context) *ProjectsGetContentCall {
	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 *ProjectsGetContentCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsGetContentCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200501")
	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/projects/{scriptId}/content")
	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{
		"scriptId": c.scriptId,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "script.projects.getContent" call.
// Exactly one of *Content or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Content.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 *ProjectsGetContentCall) Do(opts ...googleapi.CallOption) (*Content, 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 := &Content{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Gets the content of the script project, including the code source and\nmetadata for each script file.",
	//   "flatPath": "v1/projects/{scriptId}/content",
	//   "httpMethod": "GET",
	//   "id": "script.projects.getContent",
	//   "parameterOrder": [
	//     "scriptId"
	//   ],
	//   "parameters": {
	//     "scriptId": {
	//       "description": "The script project's Drive ID.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "versionNumber": {
	//       "description": "The version number of the project to retrieve. If not provided, the\nproject's HEAD version is returned.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     }
	//   },
	//   "path": "v1/projects/{scriptId}/content",
	//   "response": {
	//     "$ref": "Content"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/script.projects",
	//     "https://www.googleapis.com/auth/script.projects.readonly"
	//   ]
	// }

}

// method id "script.projects.getMetrics":

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

// GetMetrics: Get metrics data for scripts, such as number of
// executions and
// active users.
func (r *ProjectsService) GetMetrics(scriptId string) *ProjectsGetMetricsCall {
	c := &ProjectsGetMetricsCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.scriptId = scriptId
	return c
}

// MetricsFilterDeploymentId sets the optional parameter
// "metricsFilter.deploymentId": Optional field indicating a specific
// deployment to retrieve metrics from.
func (c *ProjectsGetMetricsCall) MetricsFilterDeploymentId(metricsFilterDeploymentId string) *ProjectsGetMetricsCall {
	c.urlParams_.Set("metricsFilter.deploymentId", metricsFilterDeploymentId)
	return c
}

// MetricsGranularity sets the optional parameter "metricsGranularity":
// Required field indicating what granularity of metrics are returned.
//
// Possible values:
//   "UNSPECIFIED_GRANULARITY"
//   "WEEKLY"
//   "DAILY"
func (c *ProjectsGetMetricsCall) MetricsGranularity(metricsGranularity string) *ProjectsGetMetricsCall {
	c.urlParams_.Set("metricsGranularity", metricsGranularity)
	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 *ProjectsGetMetricsCall) Fields(s ...googleapi.Field) *ProjectsGetMetricsCall {
	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 *ProjectsGetMetricsCall) IfNoneMatch(entityTag string) *ProjectsGetMetricsCall {
	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 *ProjectsGetMetricsCall) Context(ctx context.Context) *ProjectsGetMetricsCall {
	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 *ProjectsGetMetricsCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsGetMetricsCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200501")
	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/projects/{scriptId}/metrics")
	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{
		"scriptId": c.scriptId,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "script.projects.getMetrics" call.
// Exactly one of *Metrics or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Metrics.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 *ProjectsGetMetricsCall) Do(opts ...googleapi.CallOption) (*Metrics, 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 := &Metrics{
		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": "Get metrics data for scripts, such as number of executions and\nactive users.",
	//   "flatPath": "v1/projects/{scriptId}/metrics",
	//   "httpMethod": "GET",
	//   "id": "script.projects.getMetrics",
	//   "parameterOrder": [
	//     "scriptId"
	//   ],
	//   "parameters": {
	//     "metricsFilter.deploymentId": {
	//       "description": "Optional field indicating a specific deployment to retrieve metrics from.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "metricsGranularity": {
	//       "description": "Required field indicating what granularity of metrics are returned.",
	//       "enum": [
	//         "UNSPECIFIED_GRANULARITY",
	//         "WEEKLY",
	//         "DAILY"
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "scriptId": {
	//       "description": "Required field indicating the script to get metrics for.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/projects/{scriptId}/metrics",
	//   "response": {
	//     "$ref": "Metrics"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/script.metrics"
	//   ]
	// }

}

// method id "script.projects.updateContent":

type ProjectsUpdateContentCall struct {
	s          *Service
	scriptId   string
	content    *Content
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// UpdateContent: Updates the content of the specified script
// project.
// This content is stored as the HEAD version, and is used when the
// script is
// executed as a trigger, in the script editor, in add-on preview mode,
// or as
// a web app or Apps Script API in development mode. This clears all
// the
// existing files in the project.
func (r *ProjectsService) UpdateContent(scriptId string, content *Content) *ProjectsUpdateContentCall {
	c := &ProjectsUpdateContentCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.scriptId = scriptId
	c.content = content
	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 *ProjectsUpdateContentCall) Fields(s ...googleapi.Field) *ProjectsUpdateContentCall {
	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 *ProjectsUpdateContentCall) Context(ctx context.Context) *ProjectsUpdateContentCall {
	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 *ProjectsUpdateContentCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

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

// Do executes the "script.projects.updateContent" call.
// Exactly one of *Content or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Content.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 *ProjectsUpdateContentCall) Do(opts ...googleapi.CallOption) (*Content, 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 := &Content{
		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 the content of the specified script project.\nThis content is stored as the HEAD version, and is used when the script is\nexecuted as a trigger, in the script editor, in add-on preview mode, or as\na web app or Apps Script API in development mode. This clears all the\nexisting files in the project.",
	//   "flatPath": "v1/projects/{scriptId}/content",
	//   "httpMethod": "PUT",
	//   "id": "script.projects.updateContent",
	//   "parameterOrder": [
	//     "scriptId"
	//   ],
	//   "parameters": {
	//     "scriptId": {
	//       "description": "The script project's Drive ID.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/projects/{scriptId}/content",
	//   "request": {
	//     "$ref": "Content"
	//   },
	//   "response": {
	//     "$ref": "Content"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/script.projects"
	//   ]
	// }

}

// method id "script.projects.deployments.create":

type ProjectsDeploymentsCreateCall struct {
	s                *Service
	scriptId         string
	deploymentconfig *DeploymentConfig
	urlParams_       gensupport.URLParams
	ctx_             context.Context
	header_          http.Header
}

// Create: Creates a deployment of an Apps Script project.
func (r *ProjectsDeploymentsService) Create(scriptId string, deploymentconfig *DeploymentConfig) *ProjectsDeploymentsCreateCall {
	c := &ProjectsDeploymentsCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.scriptId = scriptId
	c.deploymentconfig = deploymentconfig
	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 *ProjectsDeploymentsCreateCall) Fields(s ...googleapi.Field) *ProjectsDeploymentsCreateCall {
	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 *ProjectsDeploymentsCreateCall) Context(ctx context.Context) *ProjectsDeploymentsCreateCall {
	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 *ProjectsDeploymentsCreateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsDeploymentsCreateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200501")
	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.deploymentconfig)
	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/projects/{scriptId}/deployments")
	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{
		"scriptId": c.scriptId,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "script.projects.deployments.create" call.
// Exactly one of *Deployment or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Deployment.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 *ProjectsDeploymentsCreateCall) Do(opts ...googleapi.CallOption) (*Deployment, 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 := &Deployment{
		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 deployment of an Apps Script project.",
	//   "flatPath": "v1/projects/{scriptId}/deployments",
	//   "httpMethod": "POST",
	//   "id": "script.projects.deployments.create",
	//   "parameterOrder": [
	//     "scriptId"
	//   ],
	//   "parameters": {
	//     "scriptId": {
	//       "description": "The script project's Drive ID.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/projects/{scriptId}/deployments",
	//   "request": {
	//     "$ref": "DeploymentConfig"
	//   },
	//   "response": {
	//     "$ref": "Deployment"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/script.deployments"
	//   ]
	// }

}

// method id "script.projects.deployments.delete":

type ProjectsDeploymentsDeleteCall struct {
	s            *Service
	scriptId     string
	deploymentId string
	urlParams_   gensupport.URLParams
	ctx_         context.Context
	header_      http.Header
}

// Delete: Deletes a deployment of an Apps Script project.
func (r *ProjectsDeploymentsService) Delete(scriptId string, deploymentId string) *ProjectsDeploymentsDeleteCall {
	c := &ProjectsDeploymentsDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.scriptId = scriptId
	c.deploymentId = deploymentId
	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 *ProjectsDeploymentsDeleteCall) Fields(s ...googleapi.Field) *ProjectsDeploymentsDeleteCall {
	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 *ProjectsDeploymentsDeleteCall) Context(ctx context.Context) *ProjectsDeploymentsDeleteCall {
	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 *ProjectsDeploymentsDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsDeploymentsDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200501")
	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/projects/{scriptId}/deployments/{deploymentId}")
	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{
		"scriptId":     c.scriptId,
		"deploymentId": c.deploymentId,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "script.projects.deployments.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 *ProjectsDeploymentsDeleteCall) 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 a deployment of an Apps Script project.",
	//   "flatPath": "v1/projects/{scriptId}/deployments/{deploymentId}",
	//   "httpMethod": "DELETE",
	//   "id": "script.projects.deployments.delete",
	//   "parameterOrder": [
	//     "scriptId",
	//     "deploymentId"
	//   ],
	//   "parameters": {
	//     "deploymentId": {
	//       "description": "The deployment ID to be undeployed.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "scriptId": {
	//       "description": "The script project's Drive ID.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/projects/{scriptId}/deployments/{deploymentId}",
	//   "response": {
	//     "$ref": "Empty"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/script.deployments"
	//   ]
	// }

}

// method id "script.projects.deployments.get":

type ProjectsDeploymentsGetCall struct {
	s            *Service
	scriptId     string
	deploymentId string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Gets a deployment of an Apps Script project.
func (r *ProjectsDeploymentsService) Get(scriptId string, deploymentId string) *ProjectsDeploymentsGetCall {
	c := &ProjectsDeploymentsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.scriptId = scriptId
	c.deploymentId = deploymentId
	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 *ProjectsDeploymentsGetCall) Fields(s ...googleapi.Field) *ProjectsDeploymentsGetCall {
	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 *ProjectsDeploymentsGetCall) IfNoneMatch(entityTag string) *ProjectsDeploymentsGetCall {
	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 *ProjectsDeploymentsGetCall) Context(ctx context.Context) *ProjectsDeploymentsGetCall {
	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 *ProjectsDeploymentsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsDeploymentsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200501")
	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/projects/{scriptId}/deployments/{deploymentId}")
	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{
		"scriptId":     c.scriptId,
		"deploymentId": c.deploymentId,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "script.projects.deployments.get" call.
// Exactly one of *Deployment or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Deployment.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 *ProjectsDeploymentsGetCall) Do(opts ...googleapi.CallOption) (*Deployment, 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 := &Deployment{
		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 deployment of an Apps Script project.",
	//   "flatPath": "v1/projects/{scriptId}/deployments/{deploymentId}",
	//   "httpMethod": "GET",
	//   "id": "script.projects.deployments.get",
	//   "parameterOrder": [
	//     "scriptId",
	//     "deploymentId"
	//   ],
	//   "parameters": {
	//     "deploymentId": {
	//       "description": "The deployment ID.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "scriptId": {
	//       "description": "The script project's Drive ID.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/projects/{scriptId}/deployments/{deploymentId}",
	//   "response": {
	//     "$ref": "Deployment"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/script.deployments",
	//     "https://www.googleapis.com/auth/script.deployments.readonly"
	//   ]
	// }

}

// method id "script.projects.deployments.list":

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

// List: Lists the deployments of an Apps Script project.
func (r *ProjectsDeploymentsService) List(scriptId string) *ProjectsDeploymentsListCall {
	c := &ProjectsDeploymentsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.scriptId = scriptId
	return c
}

// PageSize sets the optional parameter "pageSize": The maximum number
// of deployments on each returned page. Defaults to 50.
func (c *ProjectsDeploymentsListCall) PageSize(pageSize int64) *ProjectsDeploymentsListCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": The token for
// continuing a previous list request on the next page. This
// should be set to the value of `nextPageToken` from a previous
// response.
func (c *ProjectsDeploymentsListCall) PageToken(pageToken string) *ProjectsDeploymentsListCall {
	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 *ProjectsDeploymentsListCall) Fields(s ...googleapi.Field) *ProjectsDeploymentsListCall {
	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 *ProjectsDeploymentsListCall) IfNoneMatch(entityTag string) *ProjectsDeploymentsListCall {
	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 *ProjectsDeploymentsListCall) Context(ctx context.Context) *ProjectsDeploymentsListCall {
	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 *ProjectsDeploymentsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsDeploymentsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200501")
	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/projects/{scriptId}/deployments")
	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{
		"scriptId": c.scriptId,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "script.projects.deployments.list" call.
// Exactly one of *ListDeploymentsResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *ListDeploymentsResponse.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 *ProjectsDeploymentsListCall) Do(opts ...googleapi.CallOption) (*ListDeploymentsResponse, 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 := &ListDeploymentsResponse{
		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 the deployments of an Apps Script project.",
	//   "flatPath": "v1/projects/{scriptId}/deployments",
	//   "httpMethod": "GET",
	//   "id": "script.projects.deployments.list",
	//   "parameterOrder": [
	//     "scriptId"
	//   ],
	//   "parameters": {
	//     "pageSize": {
	//       "description": "The maximum number of deployments on each returned page. Defaults to 50.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "The token for continuing a previous list request on the next page. This\nshould be set to the value of `nextPageToken` from a previous response.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "scriptId": {
	//       "description": "The script project's Drive ID.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/projects/{scriptId}/deployments",
	//   "response": {
	//     "$ref": "ListDeploymentsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/script.deployments",
	//     "https://www.googleapis.com/auth/script.deployments.readonly"
	//   ]
	// }

}

// 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 *ProjectsDeploymentsListCall) Pages(ctx context.Context, f func(*ListDeploymentsResponse) 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 "script.projects.deployments.update":

type ProjectsDeploymentsUpdateCall struct {
	s                       *Service
	scriptId                string
	deploymentId            string
	updatedeploymentrequest *UpdateDeploymentRequest
	urlParams_              gensupport.URLParams
	ctx_                    context.Context
	header_                 http.Header
}

// Update: Updates a deployment of an Apps Script project.
func (r *ProjectsDeploymentsService) Update(scriptId string, deploymentId string, updatedeploymentrequest *UpdateDeploymentRequest) *ProjectsDeploymentsUpdateCall {
	c := &ProjectsDeploymentsUpdateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.scriptId = scriptId
	c.deploymentId = deploymentId
	c.updatedeploymentrequest = updatedeploymentrequest
	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 *ProjectsDeploymentsUpdateCall) Fields(s ...googleapi.Field) *ProjectsDeploymentsUpdateCall {
	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 *ProjectsDeploymentsUpdateCall) Context(ctx context.Context) *ProjectsDeploymentsUpdateCall {
	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 *ProjectsDeploymentsUpdateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

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

// Do executes the "script.projects.deployments.update" call.
// Exactly one of *Deployment or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Deployment.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 *ProjectsDeploymentsUpdateCall) Do(opts ...googleapi.CallOption) (*Deployment, 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 := &Deployment{
		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 deployment of an Apps Script project.",
	//   "flatPath": "v1/projects/{scriptId}/deployments/{deploymentId}",
	//   "httpMethod": "PUT",
	//   "id": "script.projects.deployments.update",
	//   "parameterOrder": [
	//     "scriptId",
	//     "deploymentId"
	//   ],
	//   "parameters": {
	//     "deploymentId": {
	//       "description": "The deployment ID for this deployment.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "scriptId": {
	//       "description": "The script project's Drive ID.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/projects/{scriptId}/deployments/{deploymentId}",
	//   "request": {
	//     "$ref": "UpdateDeploymentRequest"
	//   },
	//   "response": {
	//     "$ref": "Deployment"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/script.deployments"
	//   ]
	// }

}

// method id "script.projects.versions.create":

type ProjectsVersionsCreateCall struct {
	s          *Service
	scriptId   string
	version    *Version
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Create: Creates a new immutable version using the current code, with
// a unique
// version number.
func (r *ProjectsVersionsService) Create(scriptId string, version *Version) *ProjectsVersionsCreateCall {
	c := &ProjectsVersionsCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.scriptId = scriptId
	c.version = version
	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 *ProjectsVersionsCreateCall) Fields(s ...googleapi.Field) *ProjectsVersionsCreateCall {
	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 *ProjectsVersionsCreateCall) Context(ctx context.Context) *ProjectsVersionsCreateCall {
	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 *ProjectsVersionsCreateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsVersionsCreateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200501")
	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.version)
	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/projects/{scriptId}/versions")
	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{
		"scriptId": c.scriptId,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "script.projects.versions.create" call.
// Exactly one of *Version or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Version.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 *ProjectsVersionsCreateCall) Do(opts ...googleapi.CallOption) (*Version, 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 := &Version{
		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 immutable version using the current code, with a unique\nversion number.",
	//   "flatPath": "v1/projects/{scriptId}/versions",
	//   "httpMethod": "POST",
	//   "id": "script.projects.versions.create",
	//   "parameterOrder": [
	//     "scriptId"
	//   ],
	//   "parameters": {
	//     "scriptId": {
	//       "description": "The script project's Drive ID.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/projects/{scriptId}/versions",
	//   "request": {
	//     "$ref": "Version"
	//   },
	//   "response": {
	//     "$ref": "Version"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/script.projects"
	//   ]
	// }

}

// method id "script.projects.versions.get":

type ProjectsVersionsGetCall struct {
	s             *Service
	scriptId      string
	versionNumber int64
	urlParams_    gensupport.URLParams
	ifNoneMatch_  string
	ctx_          context.Context
	header_       http.Header
}

// Get: Gets a version of a script project.
func (r *ProjectsVersionsService) Get(scriptId string, versionNumber int64) *ProjectsVersionsGetCall {
	c := &ProjectsVersionsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.scriptId = scriptId
	c.versionNumber = versionNumber
	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 *ProjectsVersionsGetCall) Fields(s ...googleapi.Field) *ProjectsVersionsGetCall {
	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 *ProjectsVersionsGetCall) IfNoneMatch(entityTag string) *ProjectsVersionsGetCall {
	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 *ProjectsVersionsGetCall) Context(ctx context.Context) *ProjectsVersionsGetCall {
	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 *ProjectsVersionsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsVersionsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200501")
	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/projects/{scriptId}/versions/{versionNumber}")
	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{
		"scriptId":      c.scriptId,
		"versionNumber": strconv.FormatInt(c.versionNumber, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "script.projects.versions.get" call.
// Exactly one of *Version or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Version.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 *ProjectsVersionsGetCall) Do(opts ...googleapi.CallOption) (*Version, 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 := &Version{
		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 version of a script project.",
	//   "flatPath": "v1/projects/{scriptId}/versions/{versionNumber}",
	//   "httpMethod": "GET",
	//   "id": "script.projects.versions.get",
	//   "parameterOrder": [
	//     "scriptId",
	//     "versionNumber"
	//   ],
	//   "parameters": {
	//     "scriptId": {
	//       "description": "The script project's Drive ID.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "versionNumber": {
	//       "description": "The version number.",
	//       "format": "int32",
	//       "location": "path",
	//       "required": true,
	//       "type": "integer"
	//     }
	//   },
	//   "path": "v1/projects/{scriptId}/versions/{versionNumber}",
	//   "response": {
	//     "$ref": "Version"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/script.projects",
	//     "https://www.googleapis.com/auth/script.projects.readonly"
	//   ]
	// }

}

// method id "script.projects.versions.list":

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

// List: List the versions of a script project.
func (r *ProjectsVersionsService) List(scriptId string) *ProjectsVersionsListCall {
	c := &ProjectsVersionsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.scriptId = scriptId
	return c
}

// PageSize sets the optional parameter "pageSize": The maximum number
// of versions on each returned page. Defaults to 50.
func (c *ProjectsVersionsListCall) PageSize(pageSize int64) *ProjectsVersionsListCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": The token for
// continuing a previous list request on the next page. This
// should be set to the value of `nextPageToken` from a previous
// response.
func (c *ProjectsVersionsListCall) PageToken(pageToken string) *ProjectsVersionsListCall {
	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 *ProjectsVersionsListCall) Fields(s ...googleapi.Field) *ProjectsVersionsListCall {
	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 *ProjectsVersionsListCall) IfNoneMatch(entityTag string) *ProjectsVersionsListCall {
	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 *ProjectsVersionsListCall) Context(ctx context.Context) *ProjectsVersionsListCall {
	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 *ProjectsVersionsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsVersionsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200501")
	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/projects/{scriptId}/versions")
	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{
		"scriptId": c.scriptId,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "script.projects.versions.list" call.
// Exactly one of *ListVersionsResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *ListVersionsResponse.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 *ProjectsVersionsListCall) Do(opts ...googleapi.CallOption) (*ListVersionsResponse, 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 := &ListVersionsResponse{
		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 the versions of a script project.",
	//   "flatPath": "v1/projects/{scriptId}/versions",
	//   "httpMethod": "GET",
	//   "id": "script.projects.versions.list",
	//   "parameterOrder": [
	//     "scriptId"
	//   ],
	//   "parameters": {
	//     "pageSize": {
	//       "description": "The maximum number of versions on each returned page. Defaults to 50.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "The token for continuing a previous list request on the next page. This\nshould be set to the value of `nextPageToken` from a previous response.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "scriptId": {
	//       "description": "The script project's Drive ID.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/projects/{scriptId}/versions",
	//   "response": {
	//     "$ref": "ListVersionsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/script.projects",
	//     "https://www.googleapis.com/auth/script.projects.readonly"
	//   ]
	// }

}

// 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 *ProjectsVersionsListCall) Pages(ctx context.Context, f func(*ListVersionsResponse) 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 "script.scripts.run":

type ScriptsRunCall struct {
	s                *Service
	scriptId         string
	executionrequest *ExecutionRequest
	urlParams_       gensupport.URLParams
	ctx_             context.Context
	header_          http.Header
}

// Run: Runs a function in an Apps Script project. The script project
// must be
// deployed for use with the Apps Script API and the calling application
// must
// share the same Cloud Platform project.
//
// This method requires authorization with an OAuth 2.0 token that
// includes at
// least one of the scopes listed in
// the
// [Authorization](#authorization-scopes) section; script projects that
// do not
// require authorization cannot be executed through this API. To find
// the
// correct scopes to include in the authentication token, open the
// project in
// the script editor, then select **File > Project properties** and
// click the
// **Scopes** tab.
//
// The error `403, PERMISSION_DENIED: The caller does not have
// permission`
// indicates that the Cloud Platform project used to authorize the
// request is
// not the same as the one used by the script.
func (r *ScriptsService) Run(scriptId string, executionrequest *ExecutionRequest) *ScriptsRunCall {
	c := &ScriptsRunCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.scriptId = scriptId
	c.executionrequest = executionrequest
	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 *ScriptsRunCall) Fields(s ...googleapi.Field) *ScriptsRunCall {
	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 *ScriptsRunCall) Context(ctx context.Context) *ScriptsRunCall {
	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 *ScriptsRunCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ScriptsRunCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200501")
	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.executionrequest)
	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/scripts/{scriptId}:run")
	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{
		"scriptId": c.scriptId,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "script.scripts.run" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *ScriptsRunCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Runs a function in an Apps Script project. The script project must be\ndeployed for use with the Apps Script API and the calling application must\nshare the same Cloud Platform project.\n\nThis method requires authorization with an OAuth 2.0 token that includes at\nleast one of the scopes listed in the\n[Authorization](#authorization-scopes) section; script projects that do not\nrequire authorization cannot be executed through this API. To find the\ncorrect scopes to include in the authentication token, open the project in\nthe script editor, then select **File \u003e Project properties** and click the\n**Scopes** tab.\n\nThe error `403, PERMISSION_DENIED: The caller does not have permission`\nindicates that the Cloud Platform project used to authorize the request is\nnot the same as the one used by the script.",
	//   "flatPath": "v1/scripts/{scriptId}:run",
	//   "httpMethod": "POST",
	//   "id": "script.scripts.run",
	//   "parameterOrder": [
	//     "scriptId"
	//   ],
	//   "parameters": {
	//     "scriptId": {
	//       "description": "The script ID of the script to be executed. To find the script ID, open\nthe project in the script editor and select **File \u003e Project properties**.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/scripts/{scriptId}:run",
	//   "request": {
	//     "$ref": "ExecutionRequest"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://mail.google.com/",
	//     "https://www.google.com/calendar/feeds",
	//     "https://www.google.com/m8/feeds",
	//     "https://www.googleapis.com/auth/admin.directory.group",
	//     "https://www.googleapis.com/auth/admin.directory.user",
	//     "https://www.googleapis.com/auth/documents",
	//     "https://www.googleapis.com/auth/drive",
	//     "https://www.googleapis.com/auth/forms",
	//     "https://www.googleapis.com/auth/forms.currentonly",
	//     "https://www.googleapis.com/auth/groups",
	//     "https://www.googleapis.com/auth/spreadsheets",
	//     "https://www.googleapis.com/auth/userinfo.email"
	//   ]
	// }

}
