// 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 driveactivity provides access to the Drive Activity API.
//
// For product documentation, see: https://developers.google.com/drive/activity/
//
// Creating a client
//
// Usage example:
//
//   import "google.golang.org/api/driveactivity/v2"
//   ...
//   ctx := context.Background()
//   driveactivityService, err := driveactivity.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:
//
//   driveactivityService, err := driveactivity.NewService(ctx, option.WithScopes(driveactivity.DriveActivityReadonlyScope))
//
// To use an API key for authentication (note: some APIs do not support API keys), use option.WithAPIKey:
//
//   driveactivityService, err := driveactivity.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, ...)
//   driveactivityService, err := driveactivity.NewService(ctx, option.WithTokenSource(config.TokenSource(ctx, token)))
//
// See https://godoc.org/google.golang.org/api/option/ for details on options.
package driveactivity // import "google.golang.org/api/driveactivity/v2"

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 = "driveactivity:v2"
const apiName = "driveactivity"
const apiVersion = "v2"
const basePath = "https://driveactivity.googleapis.com/"
const mtlsBasePath = "https://driveactivity.mtls.googleapis.com/"

// OAuth2 scopes used by this API.
const (
	// View and add to the activity record of files in your Google Drive
	DriveActivityScope = "https://www.googleapis.com/auth/drive.activity"

	// View the activity record of files in your Google Drive
	DriveActivityReadonlyScope = "https://www.googleapis.com/auth/drive.activity.readonly"
)

// NewService creates a new Service.
func NewService(ctx context.Context, opts ...option.ClientOption) (*Service, error) {
	scopesOption := option.WithScopes(
		"https://www.googleapis.com/auth/drive.activity",
		"https://www.googleapis.com/auth/drive.activity.readonly",
	)
	// NOTE: prepend, so we don't override user-specified scopes.
	opts = append([]option.ClientOption{scopesOption}, opts...)
	opts = append(opts, internaloption.WithDefaultEndpoint(basePath))
	opts = append(opts, internaloption.WithDefaultMTLSEndpoint(mtlsBasePath))
	client, endpoint, err := htransport.NewClient(ctx, opts...)
	if err != nil {
		return nil, err
	}
	s, err := New(client)
	if err != nil {
		return nil, err
	}
	if endpoint != "" {
		s.BasePath = endpoint
	}
	return s, nil
}

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

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

	Activity *ActivityService
}

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

func NewActivityService(s *Service) *ActivityService {
	rs := &ActivityService{s: s}
	return rs
}

type ActivityService struct {
	s *Service
}

// Action: Information about the action.
type Action struct {
	// Actor: The actor responsible for this action (or empty if all actors
	// are
	// responsible).
	Actor *Actor `json:"actor,omitempty"`

	// Detail: The type and detailed information about the action.
	Detail *ActionDetail `json:"detail,omitempty"`

	// Target: The target this action affects (or empty if affecting all
	// targets). This
	// represents the state of the target immediately after this action
	// occurred.
	Target *Target `json:"target,omitempty"`

	// TimeRange: The action occurred over this time range.
	TimeRange *TimeRange `json:"timeRange,omitempty"`

	// Timestamp: The action occurred at this specific time.
	Timestamp string `json:"timestamp,omitempty"`

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

// ActionDetail: Data describing the type and additional information of
// an action.
type ActionDetail struct {
	// Comment: A change about comments was made.
	Comment *Comment `json:"comment,omitempty"`

	// Create: An object was created.
	Create *Create `json:"create,omitempty"`

	// Delete: An object was deleted.
	Delete *Delete `json:"delete,omitempty"`

	// DlpChange: A change happened in data leak prevention status.
	DlpChange *DataLeakPreventionChange `json:"dlpChange,omitempty"`

	// Edit: An object was edited.
	Edit *Edit `json:"edit,omitempty"`

	// Move: An object was moved.
	Move *Move `json:"move,omitempty"`

	// PermissionChange: The permission on an object was changed.
	PermissionChange *PermissionChange `json:"permissionChange,omitempty"`

	// Reference: An object was referenced in an application outside of
	// Drive/Docs.
	Reference *ApplicationReference `json:"reference,omitempty"`

	// Rename: An object was renamed.
	Rename *Rename `json:"rename,omitempty"`

	// Restore: A deleted object was restored.
	Restore *Restore `json:"restore,omitempty"`

	// SettingsChange: Settings were changed.
	SettingsChange *SettingsChange `json:"settingsChange,omitempty"`

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

// Actor: The actor of a Drive activity.
type Actor struct {
	// Administrator: An administrator.
	Administrator *Administrator `json:"administrator,omitempty"`

	// Anonymous: An anonymous user.
	Anonymous *AnonymousUser `json:"anonymous,omitempty"`

	// Impersonation: An account acting on behalf of another.
	Impersonation *Impersonation `json:"impersonation,omitempty"`

	// System: A non-user actor (i.e. system triggered).
	System *SystemEvent `json:"system,omitempty"`

	// User: An end user.
	User *User `json:"user,omitempty"`

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

// Administrator: Empty message representing an administrator.
type Administrator struct {
}

// AnonymousUser: Empty message representing an anonymous user or
// indicating the authenticated
// user should be anonymized.
type AnonymousUser struct {
}

// Anyone: Represents any user (including a logged out user).
type Anyone struct {
}

// ApplicationReference: Activity in applications other than Drive.
type ApplicationReference struct {
	// Type: The reference type corresponding to this event.
	//
	// Possible values:
	//   "UNSPECIFIED_REFERENCE_TYPE" - The type is not available.
	//   "LINK" - The links of one or more Drive items were posted.
	//   "DISCUSS" - Comments were made regarding a Drive item.
	Type string `json:"type,omitempty"`

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

// Assignment: A comment with an assignment.
type Assignment struct {
	// AssignedUser: The user to whom the comment was assigned.
	AssignedUser *User `json:"assignedUser,omitempty"`

	// Subtype: The sub-type of this event.
	//
	// Possible values:
	//   "SUBTYPE_UNSPECIFIED" - Subtype not available.
	//   "ADDED" - An assignment was added.
	//   "DELETED" - An assignment was deleted.
	//   "REPLY_ADDED" - An assignment reply was added.
	//   "REPLY_DELETED" - An assignment reply was deleted.
	//   "RESOLVED" - An assignment was resolved.
	//   "REOPENED" - A resolved assignment was reopened.
	//   "REASSIGNED" - An assignment was reassigned.
	Subtype string `json:"subtype,omitempty"`

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

// Comment: A change about comments on an object.
type Comment struct {
	// Assignment: A change on an assignment.
	Assignment *Assignment `json:"assignment,omitempty"`

	// MentionedUsers: Users who are mentioned in this comment.
	MentionedUsers []*User `json:"mentionedUsers,omitempty"`

	// Post: A change on a regular posted comment.
	Post *Post `json:"post,omitempty"`

	// Suggestion: A change on a suggestion.
	Suggestion *Suggestion `json:"suggestion,omitempty"`

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

// ConsolidationStrategy: How the individual activities are
// consolidated. A set of activities may be
// consolidated into one combined activity if they are related in some
// way, such
// as one actor performing the same action on multiple targets, or
// multiple
// actors performing the same action on a single target. The strategy
// defines
// the rules for which activities are related.
type ConsolidationStrategy struct {
	// Legacy: The individual activities are consolidated using the legacy
	// strategy.
	Legacy *Legacy `json:"legacy,omitempty"`

	// None: The individual activities are not consolidated.
	None *NoConsolidation `json:"none,omitempty"`

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

// Copy: An object was created by copying an existing object.
type Copy struct {
	// OriginalObject: The the original object.
	OriginalObject *TargetReference `json:"originalObject,omitempty"`

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

// Create: An object was created.
type Create struct {
	// Copy: If present, indicates the object was created by copying an
	// existing Drive
	// object.
	Copy *Copy `json:"copy,omitempty"`

	// New: If present, indicates the object was newly created (e.g. as a
	// blank
	// document), not derived from a Drive object or external object.
	New *New1 `json:"new,omitempty"`

	// Upload: If present, indicates the object originated externally and
	// was uploaded
	// to Drive.
	Upload *Upload `json:"upload,omitempty"`

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

// DataLeakPreventionChange: A change in the object's data leak
// prevention status.
type DataLeakPreventionChange struct {
	// Type: The type of Data Leak Prevention (DLP) change.
	//
	// Possible values:
	//   "TYPE_UNSPECIFIED" - An update to the DLP state that is neither
	// FLAGGED or CLEARED.
	//   "FLAGGED" - Document has been flagged as containing sensitive
	// content.
	//   "CLEARED" - Document is no longer flagged as containing sensitive
	// content.
	Type string `json:"type,omitempty"`

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

// Delete: An object was deleted.
type Delete struct {
	// Type: The type of delete action taken.
	//
	// Possible values:
	//   "TYPE_UNSPECIFIED" - Deletion type is not available.
	//   "TRASH" - An object was put into the trash.
	//   "PERMANENT_DELETE" - An object was deleted permanently.
	Type string `json:"type,omitempty"`

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

// DeletedUser: A user whose account has since been deleted.
type DeletedUser struct {
}

// Domain: Information about a domain.
type Domain struct {
	// LegacyId: An opaque string used to identify this domain.
	LegacyId string `json:"legacyId,omitempty"`

	// Name: The name of the domain, e.g. "google.com".
	Name string `json:"name,omitempty"`

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

// Drive: Information about a shared drive.
type Drive struct {
	// Name: The resource name of the shared drive. The format
	// is
	// "COLLECTION_ID/DRIVE_ID". Clients should not assume a specific
	// collection
	// ID for this resource name.
	Name string `json:"name,omitempty"`

	// Root: The root of this shared drive.
	Root *DriveItem `json:"root,omitempty"`

	// Title: The title of the shared drive.
	Title string `json:"title,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 *Drive) MarshalJSON() ([]byte, error) {
	type NoMethod Drive
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// DriveActivity: A single Drive activity comprising one or more Actions
// by one or more
// Actors on one or more Targets. Some Action groupings occur
// spontaneously,
// such as moving an item into a shared folder triggering a permission
// change.
// Other groupings of related Actions, such as multiple Actors editing
// one item
// or moving multiple files into a new folder, are controlled by the
// selection
// of a ConsolidationStrategy in the QueryDriveActivityRequest.
type DriveActivity struct {
	// Actions: Details on all actions in this activity.
	Actions []*Action `json:"actions,omitempty"`

	// Actors: All actor(s) responsible for the activity.
	Actors []*Actor `json:"actors,omitempty"`

	// PrimaryActionDetail: Key information about the primary action for
	// this activity. This is either
	// representative, or the most important, of all actions in the
	// activity,
	// according to the ConsolidationStrategy in the request.
	PrimaryActionDetail *ActionDetail `json:"primaryActionDetail,omitempty"`

	// Targets: All Google Drive objects this activity is about (e.g. file,
	// folder, drive).
	// This represents the state of the target immediately after the
	// actions
	// occurred.
	Targets []*Target `json:"targets,omitempty"`

	// TimeRange: The activity occurred over this time range.
	TimeRange *TimeRange `json:"timeRange,omitempty"`

	// Timestamp: The activity occurred at this specific time.
	Timestamp string `json:"timestamp,omitempty"`

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

// DriveFile: A Drive item which is a file.
type DriveFile struct {
}

// DriveFolder: A Drive item which is a folder.
type DriveFolder struct {
	// Type: The type of Drive folder.
	//
	// Possible values:
	//   "TYPE_UNSPECIFIED" - The folder type is unknown.
	//   "MY_DRIVE_ROOT" - The folder is the root of a user's MyDrive.
	//   "SHARED_DRIVE_ROOT" - The folder is the root of a shared drive.
	//   "STANDARD_FOLDER" - The folder is a standard, non-root, folder.
	Type string `json:"type,omitempty"`

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

// DriveItem: A Drive item, such as a file or folder.
type DriveItem struct {
	// DriveFile: The Drive item is a file.
	DriveFile *DriveFile `json:"driveFile,omitempty"`

	// DriveFolder: The Drive item is a folder. Includes information about
	// the type of
	// folder.
	DriveFolder *DriveFolder `json:"driveFolder,omitempty"`

	// File: This field is deprecated; please use the `driveFile` field
	// instead.
	File *File `json:"file,omitempty"`

	// Folder: This field is deprecated; please use the `driveFolder` field
	// instead.
	Folder *Folder `json:"folder,omitempty"`

	// MimeType: The MIME type of the Drive item.
	// See
	// https://developers.google.com/drive/v3/web/mime-types.
	MimeType string `json:"mimeType,omitempty"`

	// Name: The target Drive item. The format is "items/ITEM_ID".
	Name string `json:"name,omitempty"`

	// Owner: Information about the owner of this Drive item.
	Owner *Owner `json:"owner,omitempty"`

	// Title: The title of the Drive item.
	Title string `json:"title,omitempty"`

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

// DriveItemReference: A lightweight reference to a Drive item, such as
// a file or folder.
type DriveItemReference struct {
	// DriveFile: The Drive item is a file.
	DriveFile *DriveFile `json:"driveFile,omitempty"`

	// DriveFolder: The Drive item is a folder. Includes information about
	// the type of
	// folder.
	DriveFolder *DriveFolder `json:"driveFolder,omitempty"`

	// File: This field is deprecated; please use the `driveFile` field
	// instead.
	File *File `json:"file,omitempty"`

	// Folder: This field is deprecated; please use the `driveFolder` field
	// instead.
	Folder *Folder `json:"folder,omitempty"`

	// Name: The target Drive item. The format is "items/ITEM_ID".
	Name string `json:"name,omitempty"`

	// Title: The title of the Drive item.
	Title string `json:"title,omitempty"`

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

// DriveReference: A lightweight reference to a shared drive.
type DriveReference struct {
	// Name: The resource name of the shared drive. The format
	// is
	// "COLLECTION_ID/DRIVE_ID". Clients should not assume a specific
	// collection
	// ID for this resource name.
	Name string `json:"name,omitempty"`

	// Title: The title of the shared drive.
	Title string `json:"title,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 *DriveReference) MarshalJSON() ([]byte, error) {
	type NoMethod DriveReference
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Edit: An empty message indicating an object was edited.
type Edit struct {
}

// File: This item is deprecated; please see `DriveFile` instead.
type File struct {
}

// FileComment: A comment on a file.
type FileComment struct {
	// LegacyCommentId: The comment in the discussion thread. This
	// identifier is an opaque string
	// compatible with the Drive API;
	// see
	// https://developers.google.com/drive/v3/reference/comments/get
	LegacyCommentId string `json:"legacyCommentId,omitempty"`

	// LegacyDiscussionId: The discussion thread to which the comment was
	// added. This identifier is an
	// opaque string compatible with the Drive API and references the
	// first
	// comment in a discussion;
	// see
	// https://developers.google.com/drive/v3/reference/comments/get
	LegacyDiscussionId string `json:"legacyDiscussionId,omitempty"`

	// LinkToDiscussion: The link to the discussion thread containing this
	// comment, for
	// example,
	// "https://docs.google.com/DOCUMENT_ID/edit?disco=THREAD_ID".
	LinkToDiscussion string `json:"linkToDiscussion,omitempty"`

	// Parent: The Drive item containing this comment.
	Parent *DriveItem `json:"parent,omitempty"`

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

// Folder: This item is deprecated; please see `DriveFolder` instead.
type Folder struct {
	// Type: This field is deprecated; please see `DriveFolder.type`
	// instead.
	//
	// Possible values:
	//   "TYPE_UNSPECIFIED" - This item is deprecated; please see
	// `DriveFolder.Type` instead.
	//   "MY_DRIVE_ROOT" - This item is deprecated; please see
	// `DriveFolder.Type` instead.
	//   "TEAM_DRIVE_ROOT" - This item is deprecated; please see
	// `DriveFolder.Type` instead.
	//   "STANDARD_FOLDER" - This item is deprecated; please see
	// `DriveFolder.Type` instead.
	Type string `json:"type,omitempty"`

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

// Group: Information about a group.
type Group struct {
	// Email: The email address of the group.
	Email string `json:"email,omitempty"`

	// Title: The title of the group.
	Title string `json:"title,omitempty"`

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

// Impersonation: Information about an impersonation, where an admin
// acts on behalf of an end
// user. Information about the acting admin is not currently available.
type Impersonation struct {
	// ImpersonatedUser: The impersonated user.
	ImpersonatedUser *User `json:"impersonatedUser,omitempty"`

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

// KnownUser: A known user.
type KnownUser struct {
	// IsCurrentUser: True if this is the user making the request.
	IsCurrentUser bool `json:"isCurrentUser,omitempty"`

	// PersonName: The identifier for this user that can be used with the
	// People API to get
	// more information. The format is "people/ACCOUNT_ID".
	// See
	// https://developers.google.com/people/.
	PersonName string `json:"personName,omitempty"`

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

// Legacy: A strategy which consolidates activities using the grouping
// rules from the
// legacy V1 Activity API. Similar actions occurring within a window of
// time
// can be grouped across multiple targets (such as moving a set of files
// at
// once) or multiple actors (such as several users editing the same
// item).
// Grouping rules for this strategy are specific to each type of action.
type Legacy struct {
}

// Move: An object was moved.
type Move struct {
	// AddedParents: The added parent object(s).
	AddedParents []*TargetReference `json:"addedParents,omitempty"`

	// RemovedParents: The removed parent object(s).
	RemovedParents []*TargetReference `json:"removedParents,omitempty"`

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

// New1: An object was created from scratch.
type New1 struct {
}

// NoConsolidation: A strategy which does no consolidation of individual
// activities.
type NoConsolidation struct {
}

// Owner: Information about the owner of a Drive item.
type Owner struct {
	// Domain: The domain of the Drive item owner.
	Domain *Domain `json:"domain,omitempty"`

	// Drive: The drive that owns the item.
	Drive *DriveReference `json:"drive,omitempty"`

	// TeamDrive: This field is deprecated; please use the `drive` field
	// instead.
	TeamDrive *TeamDriveReference `json:"teamDrive,omitempty"`

	// User: The user that owns the Drive item.
	User *User `json:"user,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 *Owner) MarshalJSON() ([]byte, error) {
	type NoMethod Owner
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Permission: The permission setting of an object.
type Permission struct {
	// AllowDiscovery: If true, the item can be discovered (e.g. in the
	// user's "Shared with me"
	// collection) without needing a link to the item.
	AllowDiscovery bool `json:"allowDiscovery,omitempty"`

	// Anyone: If set, this permission applies to anyone, even logged out
	// users.
	Anyone *Anyone `json:"anyone,omitempty"`

	// Domain: The domain to whom this permission applies.
	Domain *Domain `json:"domain,omitempty"`

	// Group: The group to whom this permission applies.
	Group *Group `json:"group,omitempty"`

	// Role: Indicates the
	// <a href="/drive/web/manage-sharing#roles">Google Drive
	// permissions
	// role</a>. The role determines a user's ability to read, write,
	// and
	// comment on items.
	//
	// Possible values:
	//   "ROLE_UNSPECIFIED" - The role is not available.
	//   "OWNER" - A role granting full access.
	//   "ORGANIZER" - A role granting the ability to manage people and
	// settings.
	//   "FILE_ORGANIZER" - A role granting the ability to contribute and
	// manage content.
	//   "EDITOR" - A role granting the ability to contribute content. This
	// role is sometimes
	// also known as "writer".
	//   "COMMENTER" - A role granting the ability to view and comment on
	// content.
	//   "VIEWER" - A role granting the ability to view content. This role
	// is sometimes also
	// known as "reader".
	//   "PUBLISHED_VIEWER" - A role granting the ability to view content
	// only after it has been
	// published to the web. This role is sometimes also known as
	// "published
	// reader". See https://support.google.com/sites/answer/6372880 for
	// more
	// information.
	Role string `json:"role,omitempty"`

	// User: The user to whom this permission applies.
	User *User `json:"user,omitempty"`

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

// PermissionChange: A change of the permission setting on an item.
type PermissionChange struct {
	// AddedPermissions: The set of permissions added by this change.
	AddedPermissions []*Permission `json:"addedPermissions,omitempty"`

	// RemovedPermissions: The set of permissions removed by this change.
	RemovedPermissions []*Permission `json:"removedPermissions,omitempty"`

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

// Post: A regular posted comment.
type Post struct {
	// Subtype: The sub-type of this event.
	//
	// Possible values:
	//   "SUBTYPE_UNSPECIFIED" - Subtype not available.
	//   "ADDED" - A post was added.
	//   "DELETED" - A post was deleted.
	//   "REPLY_ADDED" - A reply was added.
	//   "REPLY_DELETED" - A reply was deleted.
	//   "RESOLVED" - A posted comment was resolved.
	//   "REOPENED" - A posted comment was reopened.
	Subtype string `json:"subtype,omitempty"`

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

// QueryDriveActivityRequest: The request message for querying Drive
// activity.
type QueryDriveActivityRequest struct {
	// AncestorName: Return activities for this Drive folder and all
	// children and descendants.
	// The format is "items/ITEM_ID".
	AncestorName string `json:"ancestorName,omitempty"`

	// ConsolidationStrategy: Details on how to consolidate related actions
	// that make up the activity. If
	// not set, then related actions are not consolidated.
	ConsolidationStrategy *ConsolidationStrategy `json:"consolidationStrategy,omitempty"`

	// Filter: The filtering for items returned from this query request. The
	// format of the
	// filter string is a sequence of expressions, joined by an optional
	// "AND",
	// where each expression is of the form "field operator
	// value".
	//
	// Supported fields:
	//
	//   - <tt>time</tt>: Uses numerical operators on date values either in
	//     terms of milliseconds since Jan 1, 1970 or in RFC 3339 format.
	//     Examples:
	//       - <tt>time > 1452409200000 AND time <= 1492812924310</tt>
	//       - <tt>time >= "2016-01-10T01:02:03-05:00"</tt>
	//
	//   - <tt>detail.action_detail_case</tt>: Uses the "has" operator (:)
	// and
	//     either a singular value or a list of allowed action types
	// enclosed in
	//     parentheses.
	//     Examples:
	//       - <tt>detail.action_detail_case: RENAME</tt>
	//       - <tt>detail.action_detail_case:(CREATE EDIT)</tt>
	//       - <tt>-detail.action_detail_case:MOVE</tt>
	Filter string `json:"filter,omitempty"`

	// ItemName: Return activities for this Drive item. The format
	// is
	// "items/ITEM_ID".
	ItemName string `json:"itemName,omitempty"`

	// PageSize: The miminum number of activities desired in the response;
	// the server will
	// attempt to return at least this quanitity. The server may also return
	// fewer
	// activities if it has a partial response ready before the request
	// times out.
	// If not set, a default value is used.
	PageSize int64 `json:"pageSize,omitempty"`

	// PageToken: The token identifying which page of results to return. Set
	// this to the
	// next_page_token value returned from a previous query to obtain
	// the
	// following page of results. If not set, the first page of results will
	// be
	// returned.
	PageToken string `json:"pageToken,omitempty"`

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

// QueryDriveActivityResponse: Response message for querying Drive
// activity.
type QueryDriveActivityResponse struct {
	// Activities: List of activity requested.
	Activities []*DriveActivity `json:"activities,omitempty"`

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

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

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

// Rename: An object was renamed.
type Rename struct {
	// NewTitle: The new title of the drive object.
	NewTitle string `json:"newTitle,omitempty"`

	// OldTitle: The previous title of the drive object.
	OldTitle string `json:"oldTitle,omitempty"`

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

// Restore: A deleted object was restored.
type Restore struct {
	// Type: The type of restore action taken.
	//
	// Possible values:
	//   "TYPE_UNSPECIFIED" - The type is not available.
	//   "UNTRASH" - An object was restored from the trash.
	Type string `json:"type,omitempty"`

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

// RestrictionChange: Information about restriction policy changes to a
// feature.
type RestrictionChange struct {
	// Feature: The feature which had a change in restriction policy.
	//
	// Possible values:
	//   "FEATURE_UNSPECIFIED" - The feature which changed restriction
	// settings was not available.
	//   "SHARING_OUTSIDE_DOMAIN" - When restricted, this prevents items
	// from being shared outside the
	// domain.
	//   "DIRECT_SHARING" - When restricted, this prevents direct sharing of
	// individual items.
	//   "ITEM_DUPLICATION" - When restricted, this prevents actions like
	// copy, download, and print
	// that might result in uncontrolled duplicates of items.
	//   "DRIVE_FILE_STREAM" - When restricted, this prevents use of Drive
	// File Stream.
	Feature string `json:"feature,omitempty"`

	// NewRestriction: The restriction in place after the change.
	//
	// Possible values:
	//   "RESTRICTION_UNSPECIFIED" - The type of restriction is not
	// available.
	//   "UNRESTRICTED" - The feature is available without restriction.
	//   "FULLY_RESTRICTED" - The use of this feature is fully restricted.
	NewRestriction string `json:"newRestriction,omitempty"`

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

// SettingsChange: Information about settings changes.
type SettingsChange struct {
	// RestrictionChanges: The set of changes made to restrictions.
	RestrictionChanges []*RestrictionChange `json:"restrictionChanges,omitempty"`

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

// Suggestion: A suggestion.
type Suggestion struct {
	// Subtype: The sub-type of this event.
	//
	// Possible values:
	//   "SUBTYPE_UNSPECIFIED" - Subtype not available.
	//   "ADDED" - A suggestion was added.
	//   "DELETED" - A suggestion was deleted.
	//   "REPLY_ADDED" - A suggestion reply was added.
	//   "REPLY_DELETED" - A suggestion reply was deleted.
	//   "ACCEPTED" - A suggestion was accepted.
	//   "REJECTED" - A suggestion was rejected.
	//   "ACCEPT_DELETED" - An accepted suggestion was deleted.
	//   "REJECT_DELETED" - A rejected suggestion was deleted.
	Subtype string `json:"subtype,omitempty"`

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

// SystemEvent: Event triggered by system operations instead of end
// users.
type SystemEvent struct {
	// Type: The type of the system event that may triggered activity.
	//
	// Possible values:
	//   "TYPE_UNSPECIFIED" - The event type is unspecified.
	//   "USER_DELETION" - The event is a consequence of a user account
	// being deleted.
	//   "TRASH_AUTO_PURGE" - The event is due to the system automatically
	// purging trash.
	Type string `json:"type,omitempty"`

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

// Target: Information about the target of activity.
type Target struct {
	// Drive: The target is a shared drive.
	Drive *Drive `json:"drive,omitempty"`

	// DriveItem: The target is a Drive item.
	DriveItem *DriveItem `json:"driveItem,omitempty"`

	// FileComment: The target is a comment on a Drive file.
	FileComment *FileComment `json:"fileComment,omitempty"`

	// TeamDrive: This field is deprecated; please use the `drive` field
	// instead.
	TeamDrive *TeamDrive `json:"teamDrive,omitempty"`

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

// TargetReference: A lightweight reference to the target of activity.
type TargetReference struct {
	// Drive: The target is a shared drive.
	Drive *DriveReference `json:"drive,omitempty"`

	// DriveItem: The target is a Drive item.
	DriveItem *DriveItemReference `json:"driveItem,omitempty"`

	// TeamDrive: This field is deprecated; please use the `drive` field
	// instead.
	TeamDrive *TeamDriveReference `json:"teamDrive,omitempty"`

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

// TeamDrive: This item is deprecated; please see `Drive` instead.
type TeamDrive struct {
	// Name: This field is deprecated; please see `Drive.name` instead.
	Name string `json:"name,omitempty"`

	// Root: This field is deprecated; please see `Drive.root` instead.
	Root *DriveItem `json:"root,omitempty"`

	// Title: This field is deprecated; please see `Drive.title` instead.
	Title string `json:"title,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 *TeamDrive) MarshalJSON() ([]byte, error) {
	type NoMethod TeamDrive
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// TeamDriveReference: This item is deprecated; please see
// `DriveReference` instead.
type TeamDriveReference struct {
	// Name: This field is deprecated; please see `DriveReference.name`
	// instead.
	Name string `json:"name,omitempty"`

	// Title: This field is deprecated; please see `DriveReference.title`
	// instead.
	Title string `json:"title,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 *TeamDriveReference) MarshalJSON() ([]byte, error) {
	type NoMethod TeamDriveReference
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// TimeRange: Information about time ranges.
type TimeRange struct {
	// EndTime: The end of the time range.
	EndTime string `json:"endTime,omitempty"`

	// StartTime: The start of the time range.
	StartTime string `json:"startTime,omitempty"`

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

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

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

// UnknownUser: A user about whom nothing is currently known.
type UnknownUser struct {
}

// Upload: An object was uploaded into Drive.
type Upload struct {
}

// User: Information about an end user.
type User struct {
	// DeletedUser: A user whose account has since been deleted.
	DeletedUser *DeletedUser `json:"deletedUser,omitempty"`

	// KnownUser: A known user.
	KnownUser *KnownUser `json:"knownUser,omitempty"`

	// UnknownUser: A user about whom nothing is currently known.
	UnknownUser *UnknownUser `json:"unknownUser,omitempty"`

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

// method id "driveactivity.activity.query":

type ActivityQueryCall struct {
	s                         *Service
	querydriveactivityrequest *QueryDriveActivityRequest
	urlParams_                gensupport.URLParams
	ctx_                      context.Context
	header_                   http.Header
}

// Query: Query past activity in Google Drive.
func (r *ActivityService) Query(querydriveactivityrequest *QueryDriveActivityRequest) *ActivityQueryCall {
	c := &ActivityQueryCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.querydriveactivityrequest = querydriveactivityrequest
	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 *ActivityQueryCall) Fields(s ...googleapi.Field) *ActivityQueryCall {
	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 *ActivityQueryCall) Context(ctx context.Context) *ActivityQueryCall {
	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 *ActivityQueryCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ActivityQueryCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200718")
	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.querydriveactivityrequest)
	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, "v2/activity:query")
	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 "driveactivity.activity.query" call.
// Exactly one of *QueryDriveActivityResponse or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *QueryDriveActivityResponse.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 *ActivityQueryCall) Do(opts ...googleapi.CallOption) (*QueryDriveActivityResponse, 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 := &QueryDriveActivityResponse{
		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": "Query past activity in Google Drive.",
	//   "flatPath": "v2/activity:query",
	//   "httpMethod": "POST",
	//   "id": "driveactivity.activity.query",
	//   "parameterOrder": [],
	//   "parameters": {},
	//   "path": "v2/activity:query",
	//   "request": {
	//     "$ref": "QueryDriveActivityRequest"
	//   },
	//   "response": {
	//     "$ref": "QueryDriveActivityResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/drive.activity",
	//     "https://www.googleapis.com/auth/drive.activity.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 *ActivityQueryCall) Pages(ctx context.Context, f func(*QueryDriveActivityResponse) error) error {
	c.ctx_ = ctx
	defer func(pt string) { c.querydriveactivityrequest.PageToken = pt }(c.querydriveactivityrequest.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.querydriveactivityrequest.PageToken = x.NextPageToken
	}
}
