// Copyright 2023 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 issuetracker provides access to the Google Issue Tracker API.
//
// For product documentation, see: https://developers.google.com/issue-tracker/partner
//
// # Creating a client
//
// Usage example:
//
//	import "go.skia.org/infra/go/issuetracker/v1"
//	...
//	ctx := context.Background()
//	issuetrackerService, err := issuetracker.NewService(ctx)
//
// In this example, Google Application Default Credentials are used for authentication.
//
// For information on how to create and obtain Application Default Credentials, see https://developers.google.com/identity/protocols/application-default-credentials.
//
// # Other authentication options
//
// To use an API key for authentication (note: some APIs do not support API keys), use option.WithAPIKey:
//
//	issuetrackerService, err := issuetracker.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, ...)
//	issuetrackerService, err := issuetracker.NewService(ctx, option.WithTokenSource(config.TokenSource(ctx, token)))
//
// See https://godoc.org/google.golang.org/api/option/ for details on options.
package issuetracker // import "go.skia.org/infra/go/issuetracker/v1"

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

	gensupport "github.com/skia-dev/google-api-go-client/gensupport"
	googleapi "google.golang.org/api/googleapi"
	option "google.golang.org/api/option"
	htransport "google.golang.org/api/transport/http"
)

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

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

// NewService creates a new Service.
func NewService(ctx context.Context, opts ...option.ClientOption) (*Service, error) {
	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.Hotlists = NewHotlistsService(s)
	s.Issues = NewIssuesService(s)
	s.Media = NewMediaService(s)
	return s, nil
}

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

	Hotlists *HotlistsService

	Issues *IssuesService

	Media *MediaService
}

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

func NewHotlistsService(s *Service) *HotlistsService {
	rs := &HotlistsService{s: s}
	rs.Entries = NewHotlistsEntriesService(s)
	return rs
}

type HotlistsService struct {
	s *Service

	Entries *HotlistsEntriesService
}

func NewHotlistsEntriesService(s *Service) *HotlistsEntriesService {
	rs := &HotlistsEntriesService{s: s}
	return rs
}

type HotlistsEntriesService struct {
	s *Service
}

func NewIssuesService(s *Service) *IssuesService {
	rs := &IssuesService{s: s}
	rs.Attachments = NewIssuesAttachmentsService(s)
	rs.Comments = NewIssuesCommentsService(s)
	rs.IssueUpdates = NewIssuesIssueUpdatesService(s)
	return rs
}

type IssuesService struct {
	s *Service

	Attachments *IssuesAttachmentsService

	Comments *IssuesCommentsService

	IssueUpdates *IssuesIssueUpdatesService
}

func NewIssuesAttachmentsService(s *Service) *IssuesAttachmentsService {
	rs := &IssuesAttachmentsService{s: s}
	return rs
}

type IssuesAttachmentsService struct {
	s *Service
}

func NewIssuesCommentsService(s *Service) *IssuesCommentsService {
	rs := &IssuesCommentsService{s: s}
	return rs
}

type IssuesCommentsService struct {
	s *Service
}

func NewIssuesIssueUpdatesService(s *Service) *IssuesIssueUpdatesService {
	rs := &IssuesIssueUpdatesService{s: s}
	return rs
}

type IssuesIssueUpdatesService struct {
	s *Service
}

func NewMediaService(s *Service) *MediaService {
	rs := &MediaService{s: s}
	return rs
}

type MediaService struct {
	s *Service
}

// Attachment: Represents an issue attachment. Each attachment is owned
// by a single issue, designated on creation. After creation, it cannot
// be transferred to another issue.
type Attachment struct {
	// AttachmentDataRef: Proto to uniquely identify an attachment for
	// reading/writing its data.
	AttachmentDataRef *AttachmentDataRef `json:"attachmentDataRef,omitempty"`

	// AttachmentId: Output only. Unique ID.
	AttachmentId int64 `json:"attachmentId,omitempty,string"`

	// ContentType: MIME type of the data.
	ContentType string `json:"contentType,omitempty"`

	// Etag: Output only. Fingerprint of the attachment.
	Etag string `json:"etag,omitempty"`

	// Filename: Original file name.
	Filename string `json:"filename,omitempty"`

	// Length: Size of the data, in bytes.
	Length int64 `json:"length,omitempty,string"`

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

// AttachmentDataRef: Contains resource name to uniquely identify
// attachments for reading/writing.
type AttachmentDataRef struct {
	// ResourceName: Unique identifier for the attachment data.
	ResourceName string `json:"resourceName,omitempty"`

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

// CollectionUpdate: Representation of a change to a collection.
type CollectionUpdate struct {
	// AddedValues: Output only. Values added to the collection.
	AddedValues []googleapi.RawMessage `json:"addedValues,omitempty"`

	// RemovedValues: Output only. Values removed from the collection.
	RemovedValues []googleapi.RawMessage `json:"removedValues,omitempty"`

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

// CreateHotlistEntryRequest: Request object for
// IssueTracker.CreateHotlistEntry Used to add an issue to a hotlist
type CreateHotlistEntryRequest struct {
	// HotlistEntry: HotlistEntry position will not be taken into account.
	// Issues are always prepended to the hotlist and have position = 1. If
	// the issue is already present on the hotlist it will be moved to
	// position = 1.
	HotlistEntry *HotlistEntry `json:"hotlistEntry,omitempty"`

	// SignificanceOverride: Significance to assign to this hotlist entry
	// creation.
	//
	// Possible values:
	//   "EDIT_SIGNIFICANCE_UNSPECIFIED" - Default value. Let the API decide
	// the significance of an edit.
	//   "MINOR" - Describes an edit that should only send notifications to
	// users that are closely-involved with an issue or have expressed a
	// high level of interest in the issue.
	//   "MAJOR" - Describes an edit that should send notifications to all
	// users involved or interested in the issue.
	//   "BULK" - Describes an edit that was part of a bulk edit and should
	// notify users in digest form.
	SignificanceOverride string `json:"significanceOverride,omitempty"`

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

// CustomField: Represents the definition of a custom field. Exists as
// part of a Component.
type CustomField struct {
	// ComponentId: ID of the component that owns this custom field. May not
	// be changed after creation.
	ComponentId int64 `json:"componentId,omitempty,string"`

	// CustomFieldId: Output only. Unique ID. Assigned at creation time by
	// the API backend.
	CustomFieldId int64 `json:"customFieldId,omitempty,string"`

	// Description: An optional description of the custom field.
	Description string `json:"description,omitempty"`

	// EnumValues: Describes all allowed values. Used only for the ENUM
	// type.
	EnumValues []string `json:"enumValues,omitempty"`

	// Name: The name used to represent the field.
	Name string `json:"name,omitempty"`

	// Required: Whether the custom field is considered a required field in
	// the api.
	Required bool `json:"required,omitempty"`

	// Shared: Output only. An optional attribute to make the field
	// available outside the component where it's defined.
	Shared bool `json:"shared,omitempty"`

	// Type: Describes how the custom field value should be interpreted.
	//
	// Possible values:
	//   "TYPE_UNSPECIFIED" - Custom field value is undefined.
	//   "TEXT" - Custom field value is text.
	//   "DATE" - Custom field value is a google.type.Date.
	//   "ENUM" - Custom field value is an enum.
	//   "NUMERIC" - Custom field value is a number.
	//   "REPEATED_TEXT" - Custom field value is a list of text values.
	//   "REPEATED_DATE" - Custom field value is a list of date values.
	//   "REPEATED_ENUM" - Custom field value is a list of enum values.
	//   "REPEATED_NUMERIC" - Custom field value is a list of numeric
	// values.
	Type string `json:"type,omitempty"`

	// TypedDefaultValue: A default value that will be automatically set if
	// none is provided by the user.
	TypedDefaultValue *CustomFieldValue `json:"typedDefaultValue,omitempty"`

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

// CustomFieldValue: Represents a value in an instance of a custom
// field. Exists as a part of an issue.
type CustomFieldValue struct {
	// CustomFieldId: Required. The numeric ID of the custom field that
	// describes this value.
	CustomFieldId int64 `json:"customFieldId,omitempty,string"`

	// DateValue: Corresponds to CustomFieldType.DATE.
	DateValue *Date `json:"dateValue,omitempty"`

	// DisplayString: A read-only string for displaying the value,
	// regardless of type. Date strings are in ISO-8601 format.
	DisplayString string `json:"displayString,omitempty"`

	// EnumValue: Corresponds to CustomFieldType.ENUM.
	EnumValue string `json:"enumValue,omitempty"`

	// NumericValue: Corresponds to CustomFieldType.NUMERIC.
	NumericValue float64 `json:"numericValue,omitempty"`

	// RepeatedDateValue: Corresponds to CustomFieldType.REPEATED_DATE.
	RepeatedDateValue *RepeatedDate `json:"repeatedDateValue,omitempty"`

	// RepeatedEnumValue: Corresponds to CustomFieldType.REPEATED_ENUM.
	RepeatedEnumValue *RepeatedString `json:"repeatedEnumValue,omitempty"`

	// RepeatedNumericValue: Corresponds to
	// CustomFieldType.REPEATED_NUMERIC.
	RepeatedNumericValue *RepeatedDouble `json:"repeatedNumericValue,omitempty"`

	// RepeatedTextValue: Corresponds to CustomFieldType.REPEATED_TEXT.
	RepeatedTextValue *RepeatedString `json:"repeatedTextValue,omitempty"`

	// TextValue: Corresponds to CustomFieldType.TEXT.
	TextValue string `json:"textValue,omitempty"`

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

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

// Date: Represents a whole or partial calendar date, such as a
// birthday. The time of day and time zone are either specified
// elsewhere or are insignificant. The date is relative to the Gregorian
// Calendar. This can represent one of the following: * A full date,
// with non-zero year, month, and day values. * A month and day, with a
// zero year (for example, an anniversary). * A year on its own, with a
// zero month and a zero day. * A year and month, with a zero day (for
// example, a credit card expiration date). Related types: *
// google.type.TimeOfDay * google.type.DateTime *
// google.protobuf.Timestamp
type Date struct {
	// Day: Day of a month. Must be from 1 to 31 and valid for the year and
	// month, or 0 to specify a year by itself or a year and month where the
	// day isn't significant.
	Day int64 `json:"day,omitempty"`

	// Month: Month of a year. Must be from 1 to 12, or 0 to specify a year
	// without a month and day.
	Month int64 `json:"month,omitempty"`

	// Year: Year of the date. Must be from 1 to 9999, or 0 to specify a
	// date without a year.
	Year int64 `json:"year,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Day") 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. "Day") 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 *Date) MarshalJSON() ([]byte, error) {
	type NoMethod Date
	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); }
type Empty struct {
	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`
}

// FieldId: Represents an identifier that can be used to uniquely
// identify either a standard or custom field.
type FieldId struct {
	// CustomFieldId: The ID of a custom field.
	CustomFieldId int64 `json:"customFieldId,omitempty,string"`

	// StandardField: A standard system field.
	//
	// Possible values:
	//   "STANDARD_FIELD_UNSPECIFIED" - Standard field is undefined.
	//   "REPORTER" - The Reporter field.
	//   "ASSIGNEE" - The Assignee field.
	//   "VERIFIER" - The Verifier field.
	//   "CC" - The CC field.
	//   "TYPE" - The Issue Type field.
	//   "STATUS" - The Issue Status field.
	//   "PRIORITY" - The Priority field.
	//   "SEVERITY" - The Severity field.
	//   "FOUND_IN" - The Found In field.
	//   "TARGETED_TO" - The Targeted To field.
	//   "VERIFIED_IN" - The Verified In field.
	//   "IN_PRODUCTION" - The In Production field.
	StandardField string `json:"standardField,omitempty"`

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

// FieldUpdate: Represents an update to a single field in an issue.
type FieldUpdate struct {
	// CollectionUpdate: Output only. Set if the field edited is a
	// collection.
	CollectionUpdate *CollectionUpdate `json:"collectionUpdate,omitempty"`

	// Field: Output only. The name of the field this diff represents. The
	// value of field will match a name from the fields of IssueState. A
	// change in a custom field value will be named 'custom_fields', and is
	// treated as changes to a single field, rather than a collection. There
	// may be more than one custom field change in an IssueUpdate.
	Field string `json:"field,omitempty"`

	// SingleValueUpdate: Set if the field edited has a single value.
	SingleValueUpdate *SingleValueUpdate `json:"singleValueUpdate,omitempty"`

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

// HotlistEntry: An issue present in a hotlist. A collection of
// HotlistEntry's can be ordered or un-ordered. The HotlistEntry
// collection is added to or removed from by calling the
// CreateHotlistEntry and DeleteHotlistEntry methods. Although these
// methods only require view permission on the issue, the act of adding
// or removing a hotlist entry for an issue is reflected in the issue's
// change history and touches the issue modification date.
type HotlistEntry struct {
	// Issue: Output only. The actual issue, for convenience.
	Issue *Issue `json:"issue,omitempty"`

	// IssueId: Required. Numeric ID of an issue contained in a hotlist.
	IssueId int64 `json:"issueId,omitempty,string"`

	// Position: Position values for an ordered collection begin at 1 and
	// increment to the end of the collection.
	Position int64 `json:"position,omitempty"`

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

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

// Hyperlink: Represents a hyperlink.
type Hyperlink struct {
	// Href: URL.
	Href string `json:"href,omitempty"`

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

// Issue: Represents the current state of an issue.
type Issue struct {
	// Ancestors: Output only. This field is set only when the issue is the
	// FULL view. A map from a child issue ID to parent issue IDs for all of
	// the ancestors of this issue. The values are based on cache. It is not
	// transactionally guaranteed, but eventually consistent.
	Ancestors map[string]SourceIssues `json:"ancestors,omitempty"`

	// Attachments: The attachment field has different functions based on
	// usages (similar to issue_comment): * In a CreateIssueRequest, this
	// message can be used to provide attachments as part of issue creation.
	// * In the response to CreateIssue, this message contains the added
	// attachments. It includes the resource names to pass to the ByteStream
	// API to write attachment data. * In the response to GetIssue or
	// ListIssues, this field is left unset.
	Attachments []*Attachment `json:"attachments,omitempty"`

	// ChildIssueCount: Output only. This field is set only when the issue
	// is the FULL view. The number of child issues of this issue.
	ChildIssueCount int64 `json:"childIssueCount,omitempty"`

	// CreatedTime: Output only. Time when this issue was created.
	CreatedTime string `json:"createdTime,omitempty"`

	// CustomFields: Output only. The Custom Fields definitions effective in
	// this issue, as determined by the component it is currently in. For
	// the Custom Field values, see IssueState.custom_fields.
	CustomFields []*CustomField `json:"customFields,omitempty"`

	// Description: Output only. The description of this issue. This field
	// is set only when the issue is the FULL view.
	Description *IssueComment `json:"description,omitempty"`

	// Etag: Output only. The fingerprint of the issue.
	Etag string `json:"etag,omitempty"`

	// IsArchived: Output only. Whether or not the issue is in an archived
	// state. Issue archived through component archiving or per issue
	// archiving will both be considered as in an archived state.
	IsArchived bool `json:"isArchived,omitempty"`

	// IssueComment: Optional. The issue_comment field has different
	// functions based on the usage: * In a CreateIssueRequest, this message
	// should be used to provide an optional comment. Do not use this field
	// to create attachments, use the attachments field below instead. * In
	// the response to CreateIssue or ModifyIssue, this message contains the
	// added comment. * In the response to GetIssue or ListIssues, this
	// field is left unset.
	IssueComment *IssueComment `json:"issueComment,omitempty"`

	// IssueId: Output only. Unique ID. Assigned at creation time by the API
	// backend.
	IssueId int64 `json:"issueId,omitempty,string"`

	// IssueState: The current state of the issue. Will always be present.
	IssueState *IssueState `json:"issueState,omitempty"`

	// LastModifier: Output only. The last modifier of the issue.
	LastModifier *User `json:"lastModifier,omitempty"`

	// MajorModifiedTime: Output only. Time when this issue was last
	// modified by a "Major" edit. See
	// https://developers.google.com/issue-tracker/concepts/issues#edit_levels
	MajorModifiedTime string `json:"majorModifiedTime,omitempty"`

	// MinorModifiedTime: Output only. Time when this issue was last
	// modified by a "Minor" or above edit. See
	// https://developers.google.com/issue-tracker/concepts/issues#edit_levels
	MinorModifiedTime string `json:"minorModifiedTime,omitempty"`

	// ModifiedTime: Output only. Time when this issue was last modified.
	ModifiedTime string `json:"modifiedTime,omitempty"`

	// ParentIssueIds: Output only. A list of parent issue IDs.
	ParentIssueIds googleapi.Int64s `json:"parentIssueIds,omitempty"`

	// RelatedLinks: Output only. This field is set only when the issue is
	// the FULL view. Related links present in comments on the issue.
	RelatedLinks []*RelatedLink `json:"relatedLinks,omitempty"`

	// ResolvedTime: Output only. Time when this issue was resolved.
	ResolvedTime string `json:"resolvedTime,omitempty"`

	// StatusUpdate: When creating an issue the status_update field can be
	// populated to create an initial status_update on the issue. In the
	// response to GetIssue or ListIssues and the FULL view is requested, it
	// contains the latest status_update that has been put on the issue.
	StatusUpdate *StatusUpdate `json:"statusUpdate,omitempty"`

	// TrackerId: Output only. ID of the Tracker the issue belongs to. This
	// value is cached from the tracker_id of the Component that the issue
	// is in. It is not transactionally guaranteed, but eventually
	// consistent.
	TrackerId int64 `json:"trackerId,omitempty,string"`

	// UserData: Output only. IssueUserData is private to the user
	// requesting this issue.
	UserData *IssueUserData `json:"userData,omitempty"`

	// VerifiedTime: Output only. Time when this issue was verified.
	VerifiedTime string `json:"verifiedTime,omitempty"`

	// Version: Output only. The current version of this issue.
	Version int64 `json:"version,omitempty"`

	// VisibleFields: Output only. The complete, ordered list of all custom
	// fields that are visible on this issue.
	VisibleFields []*FieldId `json:"visibleFields,omitempty"`

	// VoteCount: Output only. The number of users who have upvoted this
	// issue.
	VoteCount int64 `json:"voteCount,omitempty,string"`

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

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

// IssueAccessLimit: Represents the access limit set on an issue.
type IssueAccessLimit struct {
	// AccessLevel: The access level set on an issue.
	//
	// Possible values:
	//   "ACCESS_LEVEL_UNSPECIFIED" - API will reject all access limits that
	// are unspecified.
	//   "LIMIT_NONE" - There are no access limits set on this issue.
	//   "LIMIT_VIEW" - Only actors on the issue retain view access.
	//   "LIMIT_APPEND" - Only actors on the issue retain append (e.g.
	// comment) access. Issue admins also retain access
	//   "LIMIT_VIEW_TRUSTED" - Only actors on the issue or trusted
	// (Full-time Googlers + Common tools by default) users retain view
	// access.
	AccessLevel string `json:"accessLevel,omitempty"`

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

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

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

// IssueComment: A container for user-entered text and attachments
// provided as a part of an update to an issue or issue creation. All
// fields in this message are optional. It could have been named
// "Comment", but Issue Comment was chosen to emphasize that it's a
// dependent child of issue. When IssueCommentView is unspecified, it
// will be returned in basic view.
type IssueComment struct {
	// Comment: Issue comment entered by the user.
	Comment string `json:"comment,omitempty"`

	// CommentNumber: Output only. Comment number for this issue comment.
	// This is the 1-based position of the comment in the stream of comments
	// associated with the issue.
	CommentNumber int64 `json:"commentNumber,omitempty"`

	// FormattingMode: The intended formatting mode of the comment.
	//
	// Possible values:
	//   "UNSPECIFIED_FORMATTING_MODE" - Unspecified mode. If unspecified,
	// will be treated as PLAIN mode for backwards compatibility.
	//   "PLAIN" - Plain formatting is to treat the source text without much
	// formatting, but with automatic linkification of entities and
	// collapsible quoted sections. This is the historical formatting, and
	// the default.
	//   "MARKDOWN" - Treats the source text as a Markdown document.
	//   "LITERAL" - For special cases where even the linkification does in
	// a PLAIN formatting mode might be hazardous, this treats the source
	// text literally. It does not perform any linkification or quoted
	// section treatment.
	FormattingMode string `json:"formattingMode,omitempty"`

	// IssueId: Output only. Issue ID for this issue comment. It uniquely
	// identifies the issue this comment belongs to.
	IssueId int64 `json:"issueId,omitempty,string"`

	// LastEditor: Output only. The user that last modified the comment. In
	// the context of ListIssueCommentHistory, this is the user that edited
	// the comment at any given version.
	LastEditor *User `json:"lastEditor,omitempty"`

	// ModifiedTime: Output only. The time of the last modification
	ModifiedTime string `json:"modifiedTime,omitempty"`

	// Version: Output only. Version of this issue comment. This is 0-based:
	// version 0 is the original comment, version 1 is the first change to
	// the comment, etc.
	Version int64 `json:"version,omitempty"`

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

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

// IssueReference: Represents a reference to an issue.
type IssueReference struct {
	// CommentNumber: The comment number the reference is pointing to. If
	// not referencing a specific comment, 0.
	CommentNumber int64 `json:"commentNumber,omitempty"`

	// IssueId: Issue ID.
	IssueId int64 `json:"issueId,omitempty,string"`

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

// IssueState: Contains the current state of an issue.
type IssueState struct {
	// AccessLimit: The access limit set on this issue.
	AccessLimit *IssueAccessLimit `json:"accessLimit,omitempty"`

	// Assignee: The current assignee of the issue.
	Assignee *User `json:"assignee,omitempty"`

	// BlockedByIssueIds: A list of issue ids that block completion of this
	// issue.
	BlockedByIssueIds googleapi.Int64s `json:"blockedByIssueIds,omitempty"`

	// BlockingIssueIds: A list of issue ids that are blocked by this issue.
	BlockingIssueIds googleapi.Int64s `json:"blockingIssueIds,omitempty"`

	// CanonicalIssueId: If the issue has an IssueStatus of DUPLICATE, this
	// field will be populated with the issue id this is marked as a
	// duplicate of.
	CanonicalIssueId int64 `json:"canonicalIssueId,omitempty,string"`

	// Ccs: CCed users and list addresses on this issue.
	Ccs []*User `json:"ccs,omitempty"`

	// ComponentId: Required. Component this issue belongs to.
	ComponentId int64 `json:"componentId,omitempty,string"`

	// CustomFields: The custom field values currently set on the issue.
	CustomFields []*CustomFieldValue `json:"customFields,omitempty"`

	// DuplicateIssueIds: Output only. The ids of duplicate issues that have
	// marked this one as their canonical issue.
	DuplicateIssueIds googleapi.Int64s `json:"duplicateIssueIds,omitempty"`

	// FoundInVersions: A collection of release versions affected by this
	// issue.
	FoundInVersions []string `json:"foundInVersions,omitempty"`

	// HotlistIds: All of the hotlists currently applied to the issue.
	HotlistIds googleapi.Int64s `json:"hotlistIds,omitempty"`

	// InProd: Whether or not the behavior of this issue is exhibited in
	// production.
	InProd bool `json:"inProd,omitempty"`

	// IsArchived: Output only. Whether the issue has been archived through
	// per issue archiving. Note: use Issue.is_archived to decide if the
	// issue is in an archived state because issue can also be archived
	// through component.
	IsArchived bool `json:"isArchived,omitempty"`

	// Priority: Required. The current priority of the issue.
	//
	// Possible values:
	//   "PRIORITY_UNSPECIFIED" - Unspecified. Invalid state.
	//   "P0" - P0
	//   "P1" - P1
	//   "P2" - P2
	//   "P3" - P3
	//   "P4" - P4
	Priority string `json:"priority,omitempty"`

	// Reporter: *Required except for CreateIssue calls.* The reporter of
	// the issue. On CreateIssue calls only, if not set or if set to a blank
	// email address, will be set to the id of the requesting user.
	Reporter *User `json:"reporter,omitempty"`

	// Severity: Required. The current severity of the issue.
	//
	// Possible values:
	//   "SEVERITY_UNSPECIFIED" - Unspecified. Invalid state.
	//   "S0" - S0
	//   "S1" - S1
	//   "S2" - S2
	//   "S3" - S3
	//   "S4" - S4
	Severity string `json:"severity,omitempty"`

	// Status: Required. The current state of the issue.
	//
	// Possible values:
	//   "STATUS_UNSPECIFIED" - Unspecified. Invalid state.
	//   "NEW" - Issue is unassigned.
	//   "ASSIGNED" - Issue has been assigned.
	//   "ACCEPTED" - Issue has been accepted as a task by the assignee.
	//   "FIXED" - Issue has been marked Fixed.
	//   "VERIFIED" - Issue has been marked Verified.
	//   "NOT_REPRODUCIBLE" - Issue has been marked: Won't Fix (Not
	// Reproducible).
	//   "INTENDED_BEHAVIOR" - Issue has been marked: Won't Fix (Intended
	// Behavior).
	//   "OBSOLETE" - Issue has been marked: Won't Fix (Obsolete).
	//   "INFEASIBLE" - Issue has been marked: Won't Fix (Infeasible).
	//   "DUPLICATE" - Issue has been marked as a duplicate of another
	// issue.
	Status string `json:"status,omitempty"`

	// TargetedToVersions: The targeted release versions that will include
	// the fix for this issue.
	TargetedToVersions []string `json:"targetedToVersions,omitempty"`

	// Title: Required. Short summary of the issue.
	Title string `json:"title,omitempty"`

	// Type: Required. The current type of the issue.
	//
	// Possible values:
	//   "TYPE_UNSPECIFIED" - Unspecified. Invalid state.
	//   "BUG" - Bug
	//   "FEATURE_REQUEST" - Feature Request
	//   "CUSTOMER_ISSUE" - Customer Issue
	//   "INTERNAL_CLEANUP" - Internal Cleanup
	//   "PROCESS" - Process
	//   "VULNERABILITY" - Vulnerability (e.g. security or privacy)
	//   "PRIVACY_ISSUE" - Privacy Issue
	//   "PORTFOLIO" - Portfolio (NOT SUPPORTED YET)
	//   "PROGRAM" - Program (NOT SUPPORTED YET)
	//   "PROJECT" - Project
	//   "FEATURE" - Feature
	//   "MILESTONE" - Milestone
	//   "EPIC" - Epic
	//   "STORY" - Story
	//   "TASK" - Task
	Type string `json:"type,omitempty"`

	// VerifiedInVersions: The release versions which have been confirmed as
	// verified.
	VerifiedInVersions []string `json:"verifiedInVersions,omitempty"`

	// Verifier: The current verifier of the issue.
	Verifier *User `json:"verifier,omitempty"`

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

// IssueUpdate: A set of changes made to an issue, represented as a
// collection of diffs. A collection of IssueUpdate messages can
// represent the full change history of an issue.
type IssueUpdate struct {
	// Attachments: Output only. Attachments entered by user.
	Attachments []*Attachment `json:"attachments,omitempty"`

	// Author: Output only. Author of the update.
	Author *User `json:"author,omitempty"`

	// CommentNumber: Output only. If this update has a comment, this will
	// represent the relative index of the comment. Index begins at 1.
	CommentNumber int64 `json:"commentNumber,omitempty"`

	// FieldUpdates: Output only. The set of updates representing this
	// particular Issue update.
	FieldUpdates []*FieldUpdate `json:"fieldUpdates,omitempty"`

	// IssueComment: Output only. Comment entered by the user.
	IssueComment *IssueComment `json:"issueComment,omitempty"`

	// IssueId: Output only. Issue ID for this issue update. It uniquely
	// identifies the issue this update belongs to.
	IssueId int64 `json:"issueId,omitempty,string"`

	// StatusUpdate: Output only. The StatusUpdate entered by a user.
	StatusUpdate *StatusUpdate `json:"statusUpdate,omitempty"`

	// Timestamp: Output only. Time that the Issue update occurred.
	Timestamp string `json:"timestamp,omitempty"`

	// Version: Output only. The version number of this IssueUpdate, starts
	// at 0. The version of an Issue is equal to the version of its most
	// recent IssueUpdate.
	Version int64 `json:"version,omitempty"`

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

// IssueUserData: Represents issue-related data private to a requesting
// user.
type IssueUserData struct {
	// EditableCommentNumbers: Output only. ID's of the comments the user
	// can edit.
	EditableCommentNumbers []int64 `json:"editableCommentNumbers,omitempty"`

	// HasStarred: True if the user has starred the issue.
	HasStarred bool `json:"hasStarred,omitempty"`

	// HasUpvoted: True if the user has upvoted the issue.
	HasUpvoted bool `json:"hasUpvoted,omitempty"`

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

// ListAttachmentsResponse: Response object for
// IssueTracker.ListAttachments.
type ListAttachmentsResponse struct {
	// Attachments: Metadata of attachments on the specified issue.
	Attachments []*Attachment `json:"attachments,omitempty"`

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

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

// ListIssueCommentsResponse: Response object for
// IssueTracker.ListIssueComments.
type ListIssueCommentsResponse struct {
	// IssueComments: The current page of IssueComments.
	IssueComments []*IssueComment `json:"issueComments,omitempty"`

	// NextPageToken: Pagination token for next page of results.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// TotalSize: Total number of results.
	TotalSize int64 `json:"totalSize,omitempty"`

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

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

// ListIssueUpdatesResponse: Response object for
// IssueTracker.ListIssueUpdates.
type ListIssueUpdatesResponse struct {
	// IssueUpdates: The current page of IssueUpdates.
	IssueUpdates []*IssueUpdate `json:"issueUpdates,omitempty"`

	// NextPageToken: Pagination token for next page of results.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// TotalSize: Total number of results.
	TotalSize int64 `json:"totalSize,omitempty"`

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

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

// ListIssuesResponse: Response object for IssueTracker.ListIssues.
type ListIssuesResponse struct {
	// Issues: The current page of issues.
	Issues []*Issue `json:"issues,omitempty"`

	// NextPageToken: Pagination token for next page of results.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// TotalSize: Total number of results. This is an approximation.
	TotalSize int64 `json:"totalSize,omitempty"`

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

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

// Media: Media resource.
type Media struct {
	// ResourceName: Name of the media resource.
	ResourceName string `json:"resourceName,omitempty"`

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

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

// ModifyIssueRequest: Request object for IssueTracker.ModifyIssue.
type ModifyIssueRequest struct {
	// Add: Fields present that are single value fields will replace the
	// current value. Fields that are collections will append the values
	// provided. Note that if any fields need to be set, add_mask above is
	// required. If it is not provided, the add IssueState will be ignored.
	Add *IssueState `json:"add,omitempty"`

	// AddMask: Field mask indicating what fields are set in the add
	// IssueState. Note that if any fields need to be set, this mask is
	// required. If it is not provided, the add IssueState will be ignored.
	AddMask string `json:"addMask,omitempty"`

	// IssueComment: A comment and/or attachments to append to this issue.
	IssueComment *IssueComment `json:"issueComment,omitempty"`

	// Remove: Fields present that are single value fields with an empty
	// value will clear the current value. Fields that are collections will
	// remove the values provided. Note that if any fields need to be
	// cleared, remove_mask above is required. If it is not provided, the
	// remove IssueState will be ignored.
	Remove *IssueState `json:"remove,omitempty"`

	// RemoveMask: Field mask indicating what fields are set in the remove
	// IssueState. Note that if any fields need to be cleared, this mask is
	// required. If it is not provided, the remove IssueState will be
	// ignored.
	RemoveMask string `json:"removeMask,omitempty"`

	// SignificanceOverride: Significance to assign to this issue
	// modification.
	//
	// Possible values:
	//   "EDIT_SIGNIFICANCE_UNSPECIFIED" - Default value. Let the API decide
	// the significance of an edit.
	//   "MINOR" - Describes an edit that should only send notifications to
	// users that are closely-involved with an issue or have expressed a
	// high level of interest in the issue.
	//   "MAJOR" - Describes an edit that should send notifications to all
	// users involved or interested in the issue.
	//   "BULK" - Describes an edit that was part of a bulk edit and should
	// notify users in digest form.
	SignificanceOverride string `json:"significanceOverride,omitempty"`

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

// RelatedLink: A related link is a reference within a comment to some
// other entity.
type RelatedLink struct {
	// Hyperlink: A hyperlink.
	Hyperlink *Hyperlink `json:"hyperlink,omitempty"`

	// IssueReference: A reference to another issue in the tracker.
	IssueReference *IssueReference `json:"issueReference,omitempty"`

	// SourceCommentNumber: The comment number this RelatedLink was
	// extracted from.
	SourceCommentNumber int64 `json:"sourceCommentNumber,omitempty"`

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

// RepeatedDate: A repeated Date.
type RepeatedDate struct {
	// Values: The Date values.
	Values []*Date `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 *RepeatedDate) MarshalJSON() ([]byte, error) {
	type NoMethod RepeatedDate
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// RepeatedDouble: A repeated Double.
type RepeatedDouble struct {
	// Values: The double values.
	Values []float64 `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 *RepeatedDouble) MarshalJSON() ([]byte, error) {
	type NoMethod RepeatedDouble
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// RepeatedString: A repeated String.
type RepeatedString struct {
	// Values: The string values.
	Values []string `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 *RepeatedString) MarshalJSON() ([]byte, error) {
	type NoMethod RepeatedString
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// SingleValueUpdate: If both old and new values are set, they will
// always be of the same type.
type SingleValueUpdate struct {
	// NewValue: Output only. May be null. The new value set by this
	// IssueUpdate.
	NewValue googleapi.RawMessage `json:"newValue,omitempty"`

	// OldValue: Output only. May be null. The value previous to this
	// IssueUpdate.
	OldValue googleapi.RawMessage `json:"oldValue,omitempty"`

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

// SourceIssues: Source issue IDs to store ancestor cache.
type SourceIssues struct {
	// SourceIssueIds: Parent issue IDs for parent/child relationships.
	SourceIssueIds googleapi.Int64s `json:"sourceIssueIds,omitempty"`

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

// StatusUpdate: The StatusUpdate field on an issue.
type StatusUpdate struct {
	// FormattingMode: The intended formatting mode of the update text.
	//
	// Possible values:
	//   "UNSPECIFIED_FORMATTING_MODE" - Unspecified mode. If unspecified,
	// will be treated as PLAIN mode for backwards compatibility.
	//   "PLAIN" - Plain formatting is to treat the source text without much
	// formatting, but with automatic linkification of entities and
	// collapsible quoted sections. This is the historical formatting, and
	// the default.
	//   "MARKDOWN" - Treats the source text as a Markdown document.
	//   "LITERAL" - For special cases where even the linkification does in
	// a PLAIN formatting mode might be hazardous, this treats the source
	// text literally. It does not perform any linkification or quoted
	// section treatment.
	FormattingMode string `json:"formattingMode,omitempty"`

	// IssueId: Output only. Uniquely identifies the issue this statusUpdate
	// belongs to.
	IssueId int64 `json:"issueId,omitempty,string"`

	// UpdateText: StatusUpdate entered by the user.
	UpdateText string `json:"updateText,omitempty"`

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

// User: Represents a user. The canonical identifier for a user is the
// email address. This MUST be set when updating data. When retrieving
// data, in some cases the canonical email address may not be visible to
// the caller. In this case, the email_address field will be left blank,
// and one of the other non-canonical fields may be set in its place.
type User struct {
	// EmailAddress: The user's email address, including domain name. Blank
	// (i.e. the empty string) if the user's identity is not visible to the
	// caller.
	EmailAddress string `json:"emailAddress,omitempty"`

	// ObfuscatedEmailAddress: Output only. A displayable obfuscated email
	// address. Cannot be used to update data, but may be present when
	// retrieving data if the canonical email_address is not visible to the
	// caller.
	ObfuscatedEmailAddress string `json:"obfuscatedEmailAddress,omitempty"`

	// ForceSendFields is a list of field names (e.g. "EmailAddress") 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. "EmailAddress") 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 "issuetracker.hotlists.createEntries":

type HotlistsCreateEntriesCall struct {
	s                         *Service
	hotlistId                 int64
	createhotlistentryrequest *CreateHotlistEntryRequest
	urlParams_                gensupport.URLParams
	ctx_                      context.Context
	header_                   http.Header
}

// CreateEntries: Adds an issue to a hotlist by creating a HotlistEntry.
// Returns the created HotlistEntry. Requires hotlist APPEND and issue
// VIEW permission
func (r *HotlistsService) CreateEntries(hotlistId int64, createhotlistentryrequest *CreateHotlistEntryRequest) *HotlistsCreateEntriesCall {
	c := &HotlistsCreateEntriesCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.hotlistId = hotlistId
	c.createhotlistentryrequest = createhotlistentryrequest
	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 *HotlistsCreateEntriesCall) Fields(s ...googleapi.Field) *HotlistsCreateEntriesCall {
	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 *HotlistsCreateEntriesCall) Context(ctx context.Context) *HotlistsCreateEntriesCall {
	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 *HotlistsCreateEntriesCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *HotlistsCreateEntriesCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.19.5 gdcl/20190905")
	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.createhotlistentryrequest)
	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/hotlists/{+hotlistId}/entries")
	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{
		"hotlistId": strconv.FormatInt(c.hotlistId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "issuetracker.hotlists.createEntries" call.
// Exactly one of *HotlistEntry or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *HotlistEntry.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 *HotlistsCreateEntriesCall) Do(opts ...googleapi.CallOption) (*HotlistEntry, 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 := &HotlistEntry{
		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": "Adds an issue to a hotlist by creating a HotlistEntry. Returns the created HotlistEntry. Requires hotlist APPEND and issue VIEW permission",
	//   "flatPath": "v1/hotlists/{hotlistsId}/entries",
	//   "httpMethod": "PUT",
	//   "id": "issuetracker.hotlists.createEntries",
	//   "parameterOrder": [
	//     "hotlistId"
	//   ],
	//   "parameters": {
	//     "hotlistId": {
	//       "description": "Numeric ID of the hotlist.",
	//       "format": "int64",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/hotlists/{+hotlistId}/entries",
	//   "request": {
	//     "$ref": "CreateHotlistEntryRequest"
	//   },
	//   "response": {
	//     "$ref": "HotlistEntry"
	//   }
	// }

}

// method id "issuetracker.hotlists.entries.delete":

type HotlistsEntriesDeleteCall struct {
	s          *Service
	hotlistId  int64
	issueId    int64
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Delete: Removes an issue from a hotlist by deleting hotlistEntry.
// Removing an issue from a hotlist it does not belong to will do
// nothing and return. Requires hotlist APPEND and issue VIEW permission
func (r *HotlistsEntriesService) Delete(hotlistId int64, issueId int64) *HotlistsEntriesDeleteCall {
	c := &HotlistsEntriesDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.hotlistId = hotlistId
	c.issueId = issueId
	return c
}

// SignificanceOverride sets the optional parameter
// "significanceOverride": Significance to assign to this hotlist entry
// deletion.
//
// Possible values:
//
//	"EDIT_SIGNIFICANCE_UNSPECIFIED" - Default value. Let the API decide
//
// the significance of an edit.
//
//	"MINOR" - Describes an edit that should only send notifications to
//
// users that are closely-involved with an issue or have expressed a
// high level of interest in the issue.
//
//	"MAJOR" - Describes an edit that should send notifications to all
//
// users involved or interested in the issue.
//
//	"BULK" - Describes an edit that was part of a bulk edit and should
//
// notify users in digest form.
func (c *HotlistsEntriesDeleteCall) SignificanceOverride(significanceOverride string) *HotlistsEntriesDeleteCall {
	c.urlParams_.Set("significanceOverride", significanceOverride)
	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 *HotlistsEntriesDeleteCall) Fields(s ...googleapi.Field) *HotlistsEntriesDeleteCall {
	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 *HotlistsEntriesDeleteCall) Context(ctx context.Context) *HotlistsEntriesDeleteCall {
	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 *HotlistsEntriesDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *HotlistsEntriesDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.19.5 gdcl/20190905")
	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/hotlists/{+hotlistId}/entries/{+issueId}")
	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{
		"hotlistId": strconv.FormatInt(c.hotlistId, 10),
		"issueId":   strconv.FormatInt(c.issueId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "issuetracker.hotlists.entries.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 *HotlistsEntriesDeleteCall) 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": "Removes an issue from a hotlist by deleting hotlistEntry. Removing an issue from a hotlist it does not belong to will do nothing and return. Requires hotlist APPEND and issue VIEW permission",
	//   "flatPath": "v1/hotlists/{hotlistsId}/entries/{entriesId}",
	//   "httpMethod": "DELETE",
	//   "id": "issuetracker.hotlists.entries.delete",
	//   "parameterOrder": [
	//     "hotlistId",
	//     "issueId"
	//   ],
	//   "parameters": {
	//     "hotlistId": {
	//       "description": "Numeric ID of the hotlist.",
	//       "format": "int64",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "issueId": {
	//       "description": "Numeric ID of the issue to remove from hotlist",
	//       "format": "int64",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "significanceOverride": {
	//       "description": "Significance to assign to this hotlist entry deletion.",
	//       "enum": [
	//         "EDIT_SIGNIFICANCE_UNSPECIFIED",
	//         "MINOR",
	//         "MAJOR",
	//         "BULK"
	//       ],
	//       "enumDescriptions": [
	//         "Default value. Let the API decide the significance of an edit.",
	//         "Describes an edit that should only send notifications to users that are closely-involved with an issue or have expressed a high level of interest in the issue.",
	//         "Describes an edit that should send notifications to all users involved or interested in the issue.",
	//         "Describes an edit that was part of a bulk edit and should notify users in digest form."
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/hotlists/{+hotlistId}/entries/{+issueId}",
	//   "response": {
	//     "$ref": "Empty"
	//   }
	// }

}

// method id "issuetracker.issues.create":

type IssuesCreateCall struct {
	s          *Service
	issue      *Issue
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Create: Creates a new issue within a component, and returns the new
// object.
func (r *IssuesService) Create(issue *Issue) *IssuesCreateCall {
	c := &IssuesCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.issue = issue
	return c
}

// SignificanceOverride sets the optional parameter
// "significanceOverride": Significance to assign to this issue
// creation.
//
// Possible values:
//
//	"EDIT_SIGNIFICANCE_UNSPECIFIED" - Default value. Let the API decide
//
// the significance of an edit.
//
//	"MINOR" - Describes an edit that should only send notifications to
//
// users that are closely-involved with an issue or have expressed a
// high level of interest in the issue.
//
//	"MAJOR" - Describes an edit that should send notifications to all
//
// users involved or interested in the issue.
//
//	"BULK" - Describes an edit that was part of a bulk edit and should
//
// notify users in digest form.
func (c *IssuesCreateCall) SignificanceOverride(significanceOverride string) *IssuesCreateCall {
	c.urlParams_.Set("significanceOverride", significanceOverride)
	return c
}

// TemplateOptionsApplyTemplate sets the optional parameter
// "templateOptions.applyTemplate": Whether to apply a template to the
// newly-created issue. Always true for end users who are not granted
// EDIT permission on the issue. Otherwise, default is false.
func (c *IssuesCreateCall) TemplateOptionsApplyTemplate(templateOptionsApplyTemplate bool) *IssuesCreateCall {
	c.urlParams_.Set("templateOptions.applyTemplate", fmt.Sprint(templateOptionsApplyTemplate))
	return c
}

// TemplateOptionsTemplateId sets the optional parameter
// "templateOptions.templateId": The template ID to apply to this issue.
// To use the component's default template, leave unset.
func (c *IssuesCreateCall) TemplateOptionsTemplateId(templateOptionsTemplateId int64) *IssuesCreateCall {
	c.urlParams_.Set("templateOptions.templateId", fmt.Sprint(templateOptionsTemplateId))
	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 *IssuesCreateCall) Fields(s ...googleapi.Field) *IssuesCreateCall {
	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 *IssuesCreateCall) Context(ctx context.Context) *IssuesCreateCall {
	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 *IssuesCreateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *IssuesCreateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.19.5 gdcl/20190905")
	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.issue)
	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/issues")
	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 "issuetracker.issues.create" call.
// Exactly one of *Issue or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Issue.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 *IssuesCreateCall) Do(opts ...googleapi.CallOption) (*Issue, 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 := &Issue{
		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 issue within a component, and returns the new object.",
	//   "flatPath": "v1/issues",
	//   "httpMethod": "POST",
	//   "id": "issuetracker.issues.create",
	//   "parameterOrder": [],
	//   "parameters": {
	//     "significanceOverride": {
	//       "description": "Significance to assign to this issue creation.",
	//       "enum": [
	//         "EDIT_SIGNIFICANCE_UNSPECIFIED",
	//         "MINOR",
	//         "MAJOR",
	//         "BULK"
	//       ],
	//       "enumDescriptions": [
	//         "Default value. Let the API decide the significance of an edit.",
	//         "Describes an edit that should only send notifications to users that are closely-involved with an issue or have expressed a high level of interest in the issue.",
	//         "Describes an edit that should send notifications to all users involved or interested in the issue.",
	//         "Describes an edit that was part of a bulk edit and should notify users in digest form."
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "templateOptions.applyTemplate": {
	//       "description": "Whether to apply a template to the newly-created issue. Always true for end users who are not granted EDIT permission on the issue. Otherwise, default is false.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "templateOptions.templateId": {
	//       "description": "The template ID to apply to this issue. To use the component's default template, leave unset.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/issues",
	//   "request": {
	//     "$ref": "Issue"
	//   },
	//   "response": {
	//     "$ref": "Issue"
	//   }
	// }

}

// method id "issuetracker.issues.get":

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

// Get: Gets an issue with its current state.
func (r *IssuesService) Get(issueId int64) *IssuesGetCall {
	c := &IssuesGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.issueId = issueId
	return c
}

// View sets the optional parameter "view": The view of the issue to
// return.
//
// Possible values:
//
//	"ISSUE_VIEW_UNSPECIFIED" - Unspecified. It defaults to BASIC.
//	"BASIC" - Basic fields.
//	"FULL" - Include all fields.
func (c *IssuesGetCall) View(view string) *IssuesGetCall {
	c.urlParams_.Set("view", view)
	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 *IssuesGetCall) Fields(s ...googleapi.Field) *IssuesGetCall {
	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 *IssuesGetCall) IfNoneMatch(entityTag string) *IssuesGetCall {
	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 *IssuesGetCall) Context(ctx context.Context) *IssuesGetCall {
	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 *IssuesGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

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

// Do executes the "issuetracker.issues.get" call.
// Exactly one of *Issue or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Issue.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 *IssuesGetCall) Do(opts ...googleapi.CallOption) (*Issue, 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 := &Issue{
		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 an issue with its current state.",
	//   "flatPath": "v1/issues/{issuesId}",
	//   "httpMethod": "GET",
	//   "id": "issuetracker.issues.get",
	//   "parameterOrder": [
	//     "issueId"
	//   ],
	//   "parameters": {
	//     "issueId": {
	//       "description": "Numeric ID of the issue to look up.",
	//       "format": "int64",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "view": {
	//       "description": "The view of the issue to return.",
	//       "enum": [
	//         "ISSUE_VIEW_UNSPECIFIED",
	//         "BASIC",
	//         "FULL"
	//       ],
	//       "enumDescriptions": [
	//         "Unspecified. It defaults to BASIC.",
	//         "Basic fields.",
	//         "Include all fields."
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/issues/{+issueId}",
	//   "response": {
	//     "$ref": "Issue"
	//   }
	// }

}

// method id "issuetracker.issues.list":

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

// List: Searches issues, and returns issues with their current state.
func (r *IssuesService) List() *IssuesListCall {
	c := &IssuesListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	return c
}

// OrderBy sets the optional parameter "orderBy": Order parameter. Order
// is ascending ("asc") by default, but can be defined with the sort
// field followed by a space and "asc" or "desc". Examples: "issue_id",
// "modified_time asc", Secondary sorts may be specified in
// comma-separated format. Examples: "priority asc, created_time desc"
// "custom_field:1234, modified_time desc" Valid sort fields are: *
// archived * assignee * cc_count * component_path * created_time *
// custom_field: * deletion_time * duplicate_count * found_in_versions *
// in_prod * issue_id * last_modifier * modified_time * priority *
// reporter * severity * status * targeted_to_versions * title * type *
// verified_in_versions * verified_time * verifier * vote_count
func (c *IssuesListCall) OrderBy(orderBy string) *IssuesListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageSize sets the optional parameter "pageSize": Default page_size =
// 25. Maximum page_size = 500.
func (c *IssuesListCall) PageSize(pageSize int64) *IssuesListCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": Pagination token.
func (c *IssuesListCall) PageToken(pageToken string) *IssuesListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Query sets the optional parameter "query": Required. Query language
// for issues requests is defined at:
// https://developers.google.com/issue-tracker/concepts/search-query-language
func (c *IssuesListCall) Query(query string) *IssuesListCall {
	c.urlParams_.Set("query", query)
	return c
}

// View sets the optional parameter "view": The view of the issue to
// return.
//
// Possible values:
//
//	"ISSUE_VIEW_UNSPECIFIED" - Unspecified. It defaults to BASIC.
//	"BASIC" - Basic fields.
//	"FULL" - Include all fields.
func (c *IssuesListCall) View(view string) *IssuesListCall {
	c.urlParams_.Set("view", view)
	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 *IssuesListCall) Fields(s ...googleapi.Field) *IssuesListCall {
	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 *IssuesListCall) IfNoneMatch(entityTag string) *IssuesListCall {
	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 *IssuesListCall) Context(ctx context.Context) *IssuesListCall {
	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 *IssuesListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *IssuesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.19.5 gdcl/20190905")
	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/issues")
	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 "issuetracker.issues.list" call.
// Exactly one of *ListIssuesResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *ListIssuesResponse.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 *IssuesListCall) Do(opts ...googleapi.CallOption) (*ListIssuesResponse, 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 := &ListIssuesResponse{
		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": "Searches issues, and returns issues with their current state.",
	//   "flatPath": "v1/issues",
	//   "httpMethod": "GET",
	//   "id": "issuetracker.issues.list",
	//   "parameterOrder": [],
	//   "parameters": {
	//     "orderBy": {
	//       "description": "Order parameter. Order is ascending (\"asc\") by default, but can be defined with the sort field followed by a space and \"asc\" or \"desc\". Examples: \"issue_id\", \"modified_time asc\", Secondary sorts may be specified in comma-separated format. Examples: \"priority asc, created_time desc\" \"custom_field:1234, modified_time desc\" Valid sort fields are: * archived * assignee * cc_count * component_path * created_time * custom_field: * deletion_time * duplicate_count * found_in_versions * in_prod * issue_id * last_modifier * modified_time * priority * reporter * severity * status * targeted_to_versions * title * type * verified_in_versions * verified_time * verifier * vote_count",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageSize": {
	//       "description": "Default page_size = 25. Maximum page_size = 500.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "Optional. Pagination token.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "query": {
	//       "description": "Required. Query language for issues requests is defined at: https://developers.google.com/issue-tracker/concepts/search-query-language",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "view": {
	//       "description": "The view of the issue to return.",
	//       "enum": [
	//         "ISSUE_VIEW_UNSPECIFIED",
	//         "BASIC",
	//         "FULL"
	//       ],
	//       "enumDescriptions": [
	//         "Unspecified. It defaults to BASIC.",
	//         "Basic fields.",
	//         "Include all fields."
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/issues",
	//   "response": {
	//     "$ref": "ListIssuesResponse"
	//   }
	// }

}

// 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 *IssuesListCall) Pages(ctx context.Context, f func(*ListIssuesResponse) 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 "issuetracker.issues.modify":

type IssuesModifyCall struct {
	s                  *Service
	issueId            int64
	modifyissuerequest *ModifyIssueRequest
	urlParams_         gensupport.URLParams
	ctx_               context.Context
	header_            http.Header
}

// Modify: Updates an issue based on add and remove IssueState. Returns
// the modified issue.
func (r *IssuesService) Modify(issueId int64, modifyissuerequest *ModifyIssueRequest) *IssuesModifyCall {
	c := &IssuesModifyCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.issueId = issueId
	c.modifyissuerequest = modifyissuerequest
	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 *IssuesModifyCall) Fields(s ...googleapi.Field) *IssuesModifyCall {
	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 *IssuesModifyCall) Context(ctx context.Context) *IssuesModifyCall {
	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 *IssuesModifyCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *IssuesModifyCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.19.5 gdcl/20190905")
	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.modifyissuerequest)
	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/issues/{+issueId}:modify")
	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{
		"issueId": strconv.FormatInt(c.issueId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "issuetracker.issues.modify" call.
// Exactly one of *Issue or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Issue.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 *IssuesModifyCall) Do(opts ...googleapi.CallOption) (*Issue, 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 := &Issue{
		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 an issue based on add and remove IssueState. Returns the modified issue.",
	//   "flatPath": "v1/issues/{issuesId}:modify",
	//   "httpMethod": "POST",
	//   "id": "issuetracker.issues.modify",
	//   "parameterOrder": [
	//     "issueId"
	//   ],
	//   "parameters": {
	//     "issueId": {
	//       "description": "Numeric ID of the issue to update.",
	//       "format": "int64",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/issues/{+issueId}:modify",
	//   "request": {
	//     "$ref": "ModifyIssueRequest"
	//   },
	//   "response": {
	//     "$ref": "Issue"
	//   }
	// }

}

// method id "issuetracker.issues.attachments.list":

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

// List: List attachments that belong to an issue. Only returns
// attachment metadata.
func (r *IssuesAttachmentsService) List(issueId int64) *IssuesAttachmentsListCall {
	c := &IssuesAttachmentsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.issueId = issueId
	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 *IssuesAttachmentsListCall) Fields(s ...googleapi.Field) *IssuesAttachmentsListCall {
	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 *IssuesAttachmentsListCall) IfNoneMatch(entityTag string) *IssuesAttachmentsListCall {
	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 *IssuesAttachmentsListCall) Context(ctx context.Context) *IssuesAttachmentsListCall {
	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 *IssuesAttachmentsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *IssuesAttachmentsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.19.5 gdcl/20190905")
	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/issues/{+issueId}/attachments")
	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{
		"issueId": strconv.FormatInt(c.issueId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "issuetracker.issues.attachments.list" call.
// Exactly one of *ListAttachmentsResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *ListAttachmentsResponse.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 *IssuesAttachmentsListCall) Do(opts ...googleapi.CallOption) (*ListAttachmentsResponse, 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 := &ListAttachmentsResponse{
		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 attachments that belong to an issue. Only returns attachment metadata.",
	//   "flatPath": "v1/issues/{issuesId}/attachments",
	//   "httpMethod": "GET",
	//   "id": "issuetracker.issues.attachments.list",
	//   "parameterOrder": [
	//     "issueId"
	//   ],
	//   "parameters": {
	//     "issueId": {
	//       "description": "Numeric ID of the issue.",
	//       "format": "int64",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/issues/{+issueId}/attachments",
	//   "response": {
	//     "$ref": "ListAttachmentsResponse"
	//   }
	// }

}

// method id "issuetracker.issues.comments.create":

type IssuesCommentsCreateCall struct {
	s            *Service
	issueId      int64
	issuecomment *IssueComment
	urlParams_   gensupport.URLParams
	ctx_         context.Context
	header_      http.Header
}

// Create: Creates a new issue comment in an issue
func (r *IssuesCommentsService) Create(issueId int64, issuecomment *IssueComment) *IssuesCommentsCreateCall {
	c := &IssuesCommentsCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.issueId = issueId
	c.issuecomment = issuecomment
	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 *IssuesCommentsCreateCall) Fields(s ...googleapi.Field) *IssuesCommentsCreateCall {
	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 *IssuesCommentsCreateCall) Context(ctx context.Context) *IssuesCommentsCreateCall {
	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 *IssuesCommentsCreateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *IssuesCommentsCreateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.19.5 gdcl/20190905")
	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.issuecomment)
	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/issues/{+issueId}/comments")
	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{
		"issueId": strconv.FormatInt(c.issueId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "issuetracker.issues.comments.create" call.
// Exactly one of *IssueComment or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *IssueComment.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 *IssuesCommentsCreateCall) Do(opts ...googleapi.CallOption) (*IssueComment, 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 := &IssueComment{
		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 issue comment in an issue",
	//   "flatPath": "v1/issues/{issuesId}/comments",
	//   "httpMethod": "POST",
	//   "id": "issuetracker.issues.comments.create",
	//   "parameterOrder": [
	//     "issueId"
	//   ],
	//   "parameters": {
	//     "issueId": {
	//       "description": "Numeric ID of the issue.",
	//       "format": "int64",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/issues/{+issueId}/comments",
	//   "request": {
	//     "$ref": "IssueComment"
	//   },
	//   "response": {
	//     "$ref": "IssueComment"
	//   }
	// }

}

// method id "issuetracker.issues.comments.list":

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

// List: Fetches a list of IssueComment objects.
func (r *IssuesCommentsService) List(issueId int64) *IssuesCommentsListCall {
	c := &IssuesCommentsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.issueId = issueId
	return c
}

// PageSize sets the optional parameter "pageSize": The number of
// results to return. Default 25.
func (c *IssuesCommentsListCall) PageSize(pageSize int64) *IssuesCommentsListCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": Pagination token.
func (c *IssuesCommentsListCall) PageToken(pageToken string) *IssuesCommentsListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// SortBy sets the optional parameter "sortBy": Comments are sorted by
// created_time. Can be specified as either ASC or DESC. Default is
// DESC.
func (c *IssuesCommentsListCall) SortBy(sortBy string) *IssuesCommentsListCall {
	c.urlParams_.Set("sortBy", sortBy)
	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 *IssuesCommentsListCall) Fields(s ...googleapi.Field) *IssuesCommentsListCall {
	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 *IssuesCommentsListCall) IfNoneMatch(entityTag string) *IssuesCommentsListCall {
	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 *IssuesCommentsListCall) Context(ctx context.Context) *IssuesCommentsListCall {
	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 *IssuesCommentsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *IssuesCommentsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.19.5 gdcl/20190905")
	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/issues/{+issueId}/comments")
	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{
		"issueId": strconv.FormatInt(c.issueId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "issuetracker.issues.comments.list" call.
// Exactly one of *ListIssueCommentsResponse or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *ListIssueCommentsResponse.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 *IssuesCommentsListCall) Do(opts ...googleapi.CallOption) (*ListIssueCommentsResponse, 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 := &ListIssueCommentsResponse{
		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": "Fetches a list of IssueComment objects.",
	//   "flatPath": "v1/issues/{issuesId}/comments",
	//   "httpMethod": "GET",
	//   "id": "issuetracker.issues.comments.list",
	//   "parameterOrder": [
	//     "issueId"
	//   ],
	//   "parameters": {
	//     "issueId": {
	//       "description": "Numeric ID of the issue.",
	//       "format": "int64",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "pageSize": {
	//       "description": "The number of results to return. Default 25.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "Optional. Pagination token.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortBy": {
	//       "description": "Comments are sorted by created_time. Can be specified as either ASC or DESC. Default is DESC.",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/issues/{+issueId}/comments",
	//   "response": {
	//     "$ref": "ListIssueCommentsResponse"
	//   }
	// }

}

// 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 *IssuesCommentsListCall) Pages(ctx context.Context, f func(*ListIssueCommentsResponse) 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 "issuetracker.issues.comments.update":

type IssuesCommentsUpdateCall struct {
	s             *Service
	issueId       int64
	commentNumber int64
	issuecomment  *IssueComment
	urlParams_    gensupport.URLParams
	ctx_          context.Context
	header_       http.Header
}

// Update: Updates an issue comment. NB: The comment manipulation
// methods does not use the attachment field in IssueComment.
func (r *IssuesCommentsService) Update(issueId int64, commentNumber int64, issuecomment *IssueComment) *IssuesCommentsUpdateCall {
	c := &IssuesCommentsUpdateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.issueId = issueId
	c.commentNumber = commentNumber
	c.issuecomment = issuecomment
	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 *IssuesCommentsUpdateCall) Fields(s ...googleapi.Field) *IssuesCommentsUpdateCall {
	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 *IssuesCommentsUpdateCall) Context(ctx context.Context) *IssuesCommentsUpdateCall {
	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 *IssuesCommentsUpdateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *IssuesCommentsUpdateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.19.5 gdcl/20190905")
	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.issuecomment)
	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/issues/{+issueId}/comments/{+commentNumber}")
	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{
		"issueId":       strconv.FormatInt(c.issueId, 10),
		"commentNumber": strconv.FormatInt(c.commentNumber, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "issuetracker.issues.comments.update" call.
// Exactly one of *IssueComment or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *IssueComment.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 *IssuesCommentsUpdateCall) Do(opts ...googleapi.CallOption) (*IssueComment, 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 := &IssueComment{
		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 an issue comment. NB: The comment manipulation methods does not use the attachment field in IssueComment.",
	//   "flatPath": "v1/issues/{issuesId}/comments/{commentsId}",
	//   "httpMethod": "PUT",
	//   "id": "issuetracker.issues.comments.update",
	//   "parameterOrder": [
	//     "issueId",
	//     "commentNumber"
	//   ],
	//   "parameters": {
	//     "commentNumber": {
	//       "description": "The comment index of the particular issue, must match an existing number",
	//       "format": "int32",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "integer"
	//     },
	//     "issueId": {
	//       "description": "Numeric ID of the issue.",
	//       "format": "int64",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/issues/{+issueId}/comments/{+commentNumber}",
	//   "request": {
	//     "$ref": "IssueComment"
	//   },
	//   "response": {
	//     "$ref": "IssueComment"
	//   }
	// }

}

// method id "issuetracker.issues.issueUpdates.list":

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

// List: Fetch a collection of IssueUpdate objects representing the
// change history of an issue, ordered by IssueUpdate.version.
func (r *IssuesIssueUpdatesService) List(issueId int64) *IssuesIssueUpdatesListCall {
	c := &IssuesIssueUpdatesListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.issueId = issueId
	return c
}

// PageSize sets the optional parameter "pageSize": If 0, the full set
// of IssueUpdates will be returned. Default 0.
func (c *IssuesIssueUpdatesListCall) PageSize(pageSize int64) *IssuesIssueUpdatesListCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": Pagination token.
func (c *IssuesIssueUpdatesListCall) PageToken(pageToken string) *IssuesIssueUpdatesListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// SortBy sets the optional parameter "sortBy": Updates are sorted by
// version. Can be specified as either ASC or DESC. Default is DESC.
func (c *IssuesIssueUpdatesListCall) SortBy(sortBy string) *IssuesIssueUpdatesListCall {
	c.urlParams_.Set("sortBy", sortBy)
	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 *IssuesIssueUpdatesListCall) Fields(s ...googleapi.Field) *IssuesIssueUpdatesListCall {
	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 *IssuesIssueUpdatesListCall) IfNoneMatch(entityTag string) *IssuesIssueUpdatesListCall {
	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 *IssuesIssueUpdatesListCall) Context(ctx context.Context) *IssuesIssueUpdatesListCall {
	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 *IssuesIssueUpdatesListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *IssuesIssueUpdatesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.19.5 gdcl/20190905")
	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/issues/{+issueId}/issueUpdates")
	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{
		"issueId": strconv.FormatInt(c.issueId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "issuetracker.issues.issueUpdates.list" call.
// Exactly one of *ListIssueUpdatesResponse or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *ListIssueUpdatesResponse.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 *IssuesIssueUpdatesListCall) Do(opts ...googleapi.CallOption) (*ListIssueUpdatesResponse, 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 := &ListIssueUpdatesResponse{
		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": "Fetch a collection of IssueUpdate objects representing the change history of an issue, ordered by IssueUpdate.version.",
	//   "flatPath": "v1/issues/{issuesId}/issueUpdates",
	//   "httpMethod": "GET",
	//   "id": "issuetracker.issues.issueUpdates.list",
	//   "parameterOrder": [
	//     "issueId"
	//   ],
	//   "parameters": {
	//     "issueId": {
	//       "description": "Numeric ID of the issue.",
	//       "format": "int64",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "pageSize": {
	//       "description": "If 0, the full set of IssueUpdates will be returned. Default 0.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "Optional. Pagination token.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortBy": {
	//       "description": "Updates are sorted by version. Can be specified as either ASC or DESC. Default is DESC.",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/issues/{+issueId}/issueUpdates",
	//   "response": {
	//     "$ref": "ListIssueUpdatesResponse"
	//   }
	// }

}

// 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 *IssuesIssueUpdatesListCall) Pages(ctx context.Context, f func(*ListIssueUpdatesResponse) 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 "issuetracker.media.download":

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

// Download: Downloads media. Download is supported on the URI
// `/v1/media/{+name}?alt=media`.
func (r *MediaService) Download(resourceName string) *MediaDownloadCall {
	c := &MediaDownloadCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.resourceName = resourceName
	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 *MediaDownloadCall) Fields(s ...googleapi.Field) *MediaDownloadCall {
	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 *MediaDownloadCall) IfNoneMatch(entityTag string) *MediaDownloadCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do and Download
// methods. Any pending HTTP request will be aborted if the provided
// context is canceled.
func (c *MediaDownloadCall) Context(ctx context.Context) *MediaDownloadCall {
	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 *MediaDownloadCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

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

// Download fetches the API endpoint's "media" value, instead of the normal
// API response value. If the returned error is nil, the Response is guaranteed to
// have a 2xx status code. Callers must close the Response.Body as usual.
func (c *MediaDownloadCall) Download(opts ...googleapi.CallOption) (*http.Response, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("media")
	if err != nil {
		return nil, err
	}
	if err := googleapi.CheckMediaResponse(res); err != nil {
		res.Body.Close()
		return nil, err
	}
	return res, nil
}

// Do executes the "issuetracker.media.download" call.
// Exactly one of *Media or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Media.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 *MediaDownloadCall) Do(opts ...googleapi.CallOption) (*Media, 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 := &Media{
		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": "Downloads media. Download is supported on the URI `/v1/media/{+name}?alt=media`.",
	//   "flatPath": "v1/media/{mediaId}",
	//   "httpMethod": "GET",
	//   "id": "issuetracker.media.download",
	//   "parameterOrder": [
	//     "resourceName"
	//   ],
	//   "parameters": {
	//     "resourceName": {
	//       "description": "Name of the media that is being downloaded. See ReadRequest.resource_name.",
	//       "location": "path",
	//       "pattern": "^.*$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/media/{+resourceName}",
	//   "response": {
	//     "$ref": "Media"
	//   },
	//   "supportsMediaDownload": true
	// }

}

// method id "issuetracker.media.upload":

type MediaUploadCall struct {
	s            *Service
	resourceName string
	media        *Media
	urlParams_   gensupport.URLParams
	mediaInfo_   *gensupport.MediaInfo
	ctx_         context.Context
	header_      http.Header
}

// Upload: Uploads media. Upload is supported on the URI
// `/upload/v1/media/{+name}`.
func (r *MediaService) Upload(resourceName string, media *Media) *MediaUploadCall {
	c := &MediaUploadCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.resourceName = resourceName
	c.media = media
	return c
}

// Media specifies the media to upload in one or more chunks. The chunk
// size may be controlled by supplying a MediaOption generated by
// googleapi.ChunkSize. The chunk size defaults to
// googleapi.DefaultUploadChunkSize.The Content-Type header used in the
// upload request will be determined by sniffing the contents of r,
// unless a MediaOption generated by googleapi.ContentType is
// supplied.
// At most one of Media and ResumableMedia may be set.
func (c *MediaUploadCall) Media(r io.Reader, options ...googleapi.MediaOption) *MediaUploadCall {
	c.mediaInfo_ = gensupport.NewInfoFromMedia(r, options)
	return c
}

// ResumableMedia specifies the media to upload in chunks and can be
// canceled with ctx.
//
// Deprecated: use Media instead.
//
// At most one of Media and ResumableMedia may be set. mediaType
// identifies the MIME media type of the upload, such as "image/png". If
// mediaType is "", it will be auto-detected. The provided ctx will
// supersede any context previously provided to the Context method.
func (c *MediaUploadCall) ResumableMedia(ctx context.Context, r io.ReaderAt, size int64, mediaType string) *MediaUploadCall {
	c.ctx_ = ctx
	c.mediaInfo_ = gensupport.NewInfoFromResumableMedia(r, size, mediaType)
	return c
}

// ProgressUpdater provides a callback function that will be called
// after every chunk. It should be a low-latency function in order to
// not slow down the upload operation. This should only be called when
// using ResumableMedia (as opposed to Media).
func (c *MediaUploadCall) ProgressUpdater(pu googleapi.ProgressUpdater) *MediaUploadCall {
	c.mediaInfo_.SetProgressUpdater(pu)
	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 *MediaUploadCall) Fields(s ...googleapi.Field) *MediaUploadCall {
	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.
// This context will supersede any context previously provided to the
// ResumableMedia method.
func (c *MediaUploadCall) Context(ctx context.Context) *MediaUploadCall {
	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 *MediaUploadCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *MediaUploadCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.19.5 gdcl/20190905")
	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.media)
	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/media/{+resourceName}")
	if c.mediaInfo_ != nil {
		urls = strings.Replace(urls, "https://www.googleapis.com/", "https://www.googleapis.com/upload/", 1)
		c.urlParams_.Set("uploadType", c.mediaInfo_.UploadType())
	}
	if body == nil {
		body = new(bytes.Buffer)
		reqHeaders.Set("Content-Type", "application/json")
	}
	body, getBody, cleanup := c.mediaInfo_.UploadRequest(reqHeaders, body)
	defer cleanup()
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	req.GetBody = getBody
	googleapi.Expand(req.URL, map[string]string{
		"resourceName": c.resourceName,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "issuetracker.media.upload" call.
// Exactly one of *Media or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Media.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 *MediaUploadCall) Do(opts ...googleapi.CallOption) (*Media, 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
	}
	rx := c.mediaInfo_.ResumableUpload(res.Header.Get("Location"))
	if rx != nil {
		rx.Client = c.s.client
		rx.UserAgent = c.s.userAgent()
		ctx := c.ctx_
		if ctx == nil {
			ctx = context.TODO()
		}
		res, err = rx.Upload(ctx)
		if err != nil {
			return nil, err
		}
		defer res.Body.Close()
		if err := googleapi.CheckResponse(res); err != nil {
			return nil, err
		}
	}
	ret := &Media{
		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": "Uploads media. Upload is supported on the URI `/upload/v1/media/{+name}`.",
	//   "flatPath": "v1/media/{mediaId}",
	//   "httpMethod": "POST",
	//   "id": "issuetracker.media.upload",
	//   "mediaUpload": {
	//     "accept": [
	//       "*/*"
	//     ],
	//     "protocols": {
	//       "simple": {
	//         "multipart": true,
	//         "path": "/upload/v1/media/{+resourceName}"
	//       }
	//     }
	//   },
	//   "parameterOrder": [
	//     "resourceName"
	//   ],
	//   "parameters": {
	//     "resourceName": {
	//       "description": "Name of the media that is being downloaded. See ReadRequest.resource_name.",
	//       "location": "path",
	//       "pattern": "^.*$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/media/{+resourceName}",
	//   "request": {
	//     "$ref": "Media"
	//   },
	//   "response": {
	//     "$ref": "Media"
	//   },
	//   "supportsMediaUpload": true
	// }

}
