// Copyright 2020 Google LLC.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Code generated file. DO NOT EDIT.

// Package youtube provides access to the YouTube Data API v3.
//
// For product documentation, see: https://developers.google.com/youtube/
//
// Creating a client
//
// Usage example:
//
//   import "google.golang.org/api/youtube/v3"
//   ...
//   ctx := context.Background()
//   youtubeService, err := youtube.NewService(ctx)
//
// In this example, Google Application Default Credentials are used for authentication.
//
// For information on how to create and obtain Application Default Credentials, see https://developers.google.com/identity/protocols/application-default-credentials.
//
// Other authentication options
//
// By default, all available scopes (see "Constants") are used to authenticate. To restrict scopes, use option.WithScopes:
//
//   youtubeService, err := youtube.NewService(ctx, option.WithScopes(youtube.YoutubepartnerChannelAuditScope))
//
// To use an API key for authentication (note: some APIs do not support API keys), use option.WithAPIKey:
//
//   youtubeService, err := youtube.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, ...)
//   youtubeService, err := youtube.NewService(ctx, option.WithTokenSource(config.TokenSource(ctx, token)))
//
// See https://godoc.org/google.golang.org/api/option/ for details on options.
package youtube // import "google.golang.org/api/youtube/v3"

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

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

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

const apiId = "youtube:v3"
const apiName = "youtube"
const apiVersion = "v3"
const basePath = "https://www.googleapis.com/"
const mtlsBasePath = "https://www.mtls.googleapis.com/"

// OAuth2 scopes used by this API.
const (
	// Manage your YouTube account
	YoutubeScope = "https://www.googleapis.com/auth/youtube"

	// See a list of your current active channel members, their current
	// level, and when they became a member
	YoutubeChannelMembershipsCreatorScope = "https://www.googleapis.com/auth/youtube.channel-memberships.creator"

	// See, edit, and permanently delete your YouTube videos, ratings,
	// comments and captions
	YoutubeForceSslScope = "https://www.googleapis.com/auth/youtube.force-ssl"

	// View your YouTube account
	YoutubeReadonlyScope = "https://www.googleapis.com/auth/youtube.readonly"

	// Manage your YouTube videos
	YoutubeUploadScope = "https://www.googleapis.com/auth/youtube.upload"

	// View and manage your assets and associated content on YouTube
	YoutubepartnerScope = "https://www.googleapis.com/auth/youtubepartner"

	// View private information of your YouTube channel relevant during the
	// audit process with a YouTube partner
	YoutubepartnerChannelAuditScope = "https://www.googleapis.com/auth/youtubepartner-channel-audit"
)

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

// New creates a new Service. It uses the provided http.Client for requests.
//
// Deprecated: please use NewService instead.
// To provide a custom HTTP client, use option.WithHTTPClient.
// If you are using google.golang.org/api/googleapis/transport.APIKey, use option.WithAPIKey with NewService instead.
func New(client *http.Client) (*Service, error) {
	if client == nil {
		return nil, errors.New("client is nil")
	}
	s := &Service{client: client, BasePath: basePath}
	s.AbuseReports = NewAbuseReportsService(s)
	s.Activities = NewActivitiesService(s)
	s.Captions = NewCaptionsService(s)
	s.ChannelBanners = NewChannelBannersService(s)
	s.ChannelSections = NewChannelSectionsService(s)
	s.Channels = NewChannelsService(s)
	s.CommentThreads = NewCommentThreadsService(s)
	s.Comments = NewCommentsService(s)
	s.I18nLanguages = NewI18nLanguagesService(s)
	s.I18nRegions = NewI18nRegionsService(s)
	s.LiveBroadcasts = NewLiveBroadcastsService(s)
	s.LiveChatBans = NewLiveChatBansService(s)
	s.LiveChatMessages = NewLiveChatMessagesService(s)
	s.LiveChatModerators = NewLiveChatModeratorsService(s)
	s.LiveStreams = NewLiveStreamsService(s)
	s.Members = NewMembersService(s)
	s.MembershipsLevels = NewMembershipsLevelsService(s)
	s.PlaylistItems = NewPlaylistItemsService(s)
	s.Playlists = NewPlaylistsService(s)
	s.Search = NewSearchService(s)
	s.Sponsors = NewSponsorsService(s)
	s.Subscriptions = NewSubscriptionsService(s)
	s.SuperChatEvents = NewSuperChatEventsService(s)
	s.Tests = NewTestsService(s)
	s.ThirdPartyLinks = NewThirdPartyLinksService(s)
	s.Thumbnails = NewThumbnailsService(s)
	s.VideoAbuseReportReasons = NewVideoAbuseReportReasonsService(s)
	s.VideoCategories = NewVideoCategoriesService(s)
	s.Videos = NewVideosService(s)
	s.Watermarks = NewWatermarksService(s)
	return s, nil
}

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

	AbuseReports *AbuseReportsService

	Activities *ActivitiesService

	Captions *CaptionsService

	ChannelBanners *ChannelBannersService

	ChannelSections *ChannelSectionsService

	Channels *ChannelsService

	CommentThreads *CommentThreadsService

	Comments *CommentsService

	I18nLanguages *I18nLanguagesService

	I18nRegions *I18nRegionsService

	LiveBroadcasts *LiveBroadcastsService

	LiveChatBans *LiveChatBansService

	LiveChatMessages *LiveChatMessagesService

	LiveChatModerators *LiveChatModeratorsService

	LiveStreams *LiveStreamsService

	Members *MembersService

	MembershipsLevels *MembershipsLevelsService

	PlaylistItems *PlaylistItemsService

	Playlists *PlaylistsService

	Search *SearchService

	Sponsors *SponsorsService

	Subscriptions *SubscriptionsService

	SuperChatEvents *SuperChatEventsService

	Tests *TestsService

	ThirdPartyLinks *ThirdPartyLinksService

	Thumbnails *ThumbnailsService

	VideoAbuseReportReasons *VideoAbuseReportReasonsService

	VideoCategories *VideoCategoriesService

	Videos *VideosService

	Watermarks *WatermarksService
}

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

func NewAbuseReportsService(s *Service) *AbuseReportsService {
	rs := &AbuseReportsService{s: s}
	return rs
}

type AbuseReportsService struct {
	s *Service
}

func NewActivitiesService(s *Service) *ActivitiesService {
	rs := &ActivitiesService{s: s}
	return rs
}

type ActivitiesService struct {
	s *Service
}

func NewCaptionsService(s *Service) *CaptionsService {
	rs := &CaptionsService{s: s}
	return rs
}

type CaptionsService struct {
	s *Service
}

func NewChannelBannersService(s *Service) *ChannelBannersService {
	rs := &ChannelBannersService{s: s}
	return rs
}

type ChannelBannersService struct {
	s *Service
}

func NewChannelSectionsService(s *Service) *ChannelSectionsService {
	rs := &ChannelSectionsService{s: s}
	return rs
}

type ChannelSectionsService struct {
	s *Service
}

func NewChannelsService(s *Service) *ChannelsService {
	rs := &ChannelsService{s: s}
	return rs
}

type ChannelsService struct {
	s *Service
}

func NewCommentThreadsService(s *Service) *CommentThreadsService {
	rs := &CommentThreadsService{s: s}
	return rs
}

type CommentThreadsService struct {
	s *Service
}

func NewCommentsService(s *Service) *CommentsService {
	rs := &CommentsService{s: s}
	return rs
}

type CommentsService struct {
	s *Service
}

func NewI18nLanguagesService(s *Service) *I18nLanguagesService {
	rs := &I18nLanguagesService{s: s}
	return rs
}

type I18nLanguagesService struct {
	s *Service
}

func NewI18nRegionsService(s *Service) *I18nRegionsService {
	rs := &I18nRegionsService{s: s}
	return rs
}

type I18nRegionsService struct {
	s *Service
}

func NewLiveBroadcastsService(s *Service) *LiveBroadcastsService {
	rs := &LiveBroadcastsService{s: s}
	return rs
}

type LiveBroadcastsService struct {
	s *Service
}

func NewLiveChatBansService(s *Service) *LiveChatBansService {
	rs := &LiveChatBansService{s: s}
	return rs
}

type LiveChatBansService struct {
	s *Service
}

func NewLiveChatMessagesService(s *Service) *LiveChatMessagesService {
	rs := &LiveChatMessagesService{s: s}
	return rs
}

type LiveChatMessagesService struct {
	s *Service
}

func NewLiveChatModeratorsService(s *Service) *LiveChatModeratorsService {
	rs := &LiveChatModeratorsService{s: s}
	return rs
}

type LiveChatModeratorsService struct {
	s *Service
}

func NewLiveStreamsService(s *Service) *LiveStreamsService {
	rs := &LiveStreamsService{s: s}
	return rs
}

type LiveStreamsService struct {
	s *Service
}

func NewMembersService(s *Service) *MembersService {
	rs := &MembersService{s: s}
	return rs
}

type MembersService struct {
	s *Service
}

func NewMembershipsLevelsService(s *Service) *MembershipsLevelsService {
	rs := &MembershipsLevelsService{s: s}
	return rs
}

type MembershipsLevelsService struct {
	s *Service
}

func NewPlaylistItemsService(s *Service) *PlaylistItemsService {
	rs := &PlaylistItemsService{s: s}
	return rs
}

type PlaylistItemsService struct {
	s *Service
}

func NewPlaylistsService(s *Service) *PlaylistsService {
	rs := &PlaylistsService{s: s}
	return rs
}

type PlaylistsService struct {
	s *Service
}

func NewSearchService(s *Service) *SearchService {
	rs := &SearchService{s: s}
	return rs
}

type SearchService struct {
	s *Service
}

func NewSponsorsService(s *Service) *SponsorsService {
	rs := &SponsorsService{s: s}
	return rs
}

type SponsorsService struct {
	s *Service
}

func NewSubscriptionsService(s *Service) *SubscriptionsService {
	rs := &SubscriptionsService{s: s}
	return rs
}

type SubscriptionsService struct {
	s *Service
}

func NewSuperChatEventsService(s *Service) *SuperChatEventsService {
	rs := &SuperChatEventsService{s: s}
	return rs
}

type SuperChatEventsService struct {
	s *Service
}

func NewTestsService(s *Service) *TestsService {
	rs := &TestsService{s: s}
	return rs
}

type TestsService struct {
	s *Service
}

func NewThirdPartyLinksService(s *Service) *ThirdPartyLinksService {
	rs := &ThirdPartyLinksService{s: s}
	return rs
}

type ThirdPartyLinksService struct {
	s *Service
}

func NewThumbnailsService(s *Service) *ThumbnailsService {
	rs := &ThumbnailsService{s: s}
	return rs
}

type ThumbnailsService struct {
	s *Service
}

func NewVideoAbuseReportReasonsService(s *Service) *VideoAbuseReportReasonsService {
	rs := &VideoAbuseReportReasonsService{s: s}
	return rs
}

type VideoAbuseReportReasonsService struct {
	s *Service
}

func NewVideoCategoriesService(s *Service) *VideoCategoriesService {
	rs := &VideoCategoriesService{s: s}
	return rs
}

type VideoCategoriesService struct {
	s *Service
}

func NewVideosService(s *Service) *VideosService {
	rs := &VideosService{s: s}
	return rs
}

type VideosService struct {
	s *Service
}

func NewWatermarksService(s *Service) *WatermarksService {
	rs := &WatermarksService{s: s}
	return rs
}

type WatermarksService struct {
	s *Service
}

type AbuseReport struct {
	AbuseTypes []*AbuseType `json:"abuseTypes,omitempty"`

	Description string `json:"description,omitempty"`

	RelatedEntities []*RelatedEntity `json:"relatedEntities,omitempty"`

	Subject *Entity `json:"subject,omitempty"`

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

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

type AbuseType struct {
	Id string `json:"id,omitempty"`

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

// AccessPolicy: Rights management policy for YouTube resources.
type AccessPolicy struct {
	// Allowed: The value of allowed indicates whether the access to the
	// policy is allowed or denied by default.
	Allowed bool `json:"allowed,omitempty"`

	// Exception: A list of region codes that identify countries where the
	// default policy do not apply.
	Exception []string `json:"exception,omitempty"`

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

// Activity: An *activity* resource contains information about an action
// that a particular channel, or user, has taken on YouTube.The actions
// reported in activity feeds include rating a video, sharing a video,
// marking a video as a favorite, commenting on a video, uploading a
// video, and so forth. Each activity resource identifies the type of
// action, the channel associated with the action, and the resource(s)
// associated with the action, such as the video that was rated or
// uploaded.
type Activity struct {
	// ContentDetails: The contentDetails object contains information about
	// the content associated with the activity. For example, if the
	// snippet.type value is videoRated, then the contentDetails object's
	// content identifies the rated video.
	ContentDetails *ActivityContentDetails `json:"contentDetails,omitempty"`

	// Etag: Etag of this resource
	Etag string `json:"etag,omitempty"`

	// Id: The ID that YouTube uses to uniquely identify the activity.
	Id string `json:"id,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "youtube#activity".
	Kind string `json:"kind,omitempty"`

	// Snippet: The snippet object contains basic details about the
	// activity, including the activity's type and group ID.
	Snippet *ActivitySnippet `json:"snippet,omitempty"`

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

// ActivityContentDetails: Details about the content of an activity: the
// video that was shared, the channel that was subscribed to, etc.
type ActivityContentDetails struct {
	// Bulletin: The bulletin object contains details about a channel
	// bulletin post. This object is only present if the snippet.type is
	// bulletin.
	Bulletin *ActivityContentDetailsBulletin `json:"bulletin,omitempty"`

	// ChannelItem: The channelItem object contains details about a resource
	// which was added to a channel. This property is only present if the
	// snippet.type is channelItem.
	ChannelItem *ActivityContentDetailsChannelItem `json:"channelItem,omitempty"`

	// Comment: The comment object contains information about a resource
	// that received a comment. This property is only present if the
	// snippet.type is comment.
	Comment *ActivityContentDetailsComment `json:"comment,omitempty"`

	// Favorite: The favorite object contains information about a video that
	// was marked as a favorite video. This property is only present if the
	// snippet.type is favorite.
	Favorite *ActivityContentDetailsFavorite `json:"favorite,omitempty"`

	// Like: The like object contains information about a resource that
	// received a positive (like) rating. This property is only present if
	// the snippet.type is like.
	Like *ActivityContentDetailsLike `json:"like,omitempty"`

	// PlaylistItem: The playlistItem object contains information about a
	// new playlist item. This property is only present if the snippet.type
	// is playlistItem.
	PlaylistItem *ActivityContentDetailsPlaylistItem `json:"playlistItem,omitempty"`

	// PromotedItem: The promotedItem object contains details about a
	// resource which is being promoted. This property is only present if
	// the snippet.type is promotedItem.
	PromotedItem *ActivityContentDetailsPromotedItem `json:"promotedItem,omitempty"`

	// Recommendation: The recommendation object contains information about
	// a recommended resource. This property is only present if the
	// snippet.type is recommendation.
	Recommendation *ActivityContentDetailsRecommendation `json:"recommendation,omitempty"`

	// Social: The social object contains details about a social network
	// post. This property is only present if the snippet.type is social.
	Social *ActivityContentDetailsSocial `json:"social,omitempty"`

	// Subscription: The subscription object contains information about a
	// channel that a user subscribed to. This property is only present if
	// the snippet.type is subscription.
	Subscription *ActivityContentDetailsSubscription `json:"subscription,omitempty"`

	// Upload: The upload object contains information about the uploaded
	// video. This property is only present if the snippet.type is upload.
	Upload *ActivityContentDetailsUpload `json:"upload,omitempty"`

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

// ActivityContentDetailsBulletin: Details about a channel bulletin
// post.
type ActivityContentDetailsBulletin struct {
	// ResourceId: The resourceId object contains information that
	// identifies the resource associated with a bulletin post. @mutable
	// youtube.activities.insert
	ResourceId *ResourceId `json:"resourceId,omitempty"`

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

// ActivityContentDetailsChannelItem: Details about a resource which was
// added to a channel.
type ActivityContentDetailsChannelItem struct {
	// ResourceId: The resourceId object contains information that
	// identifies the resource that was added to the channel.
	ResourceId *ResourceId `json:"resourceId,omitempty"`

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

// ActivityContentDetailsComment: Information about a resource that
// received a comment.
type ActivityContentDetailsComment struct {
	// ResourceId: The resourceId object contains information that
	// identifies the resource associated with the comment.
	ResourceId *ResourceId `json:"resourceId,omitempty"`

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

// ActivityContentDetailsFavorite: Information about a video that was
// marked as a favorite video.
type ActivityContentDetailsFavorite struct {
	// ResourceId: The resourceId object contains information that
	// identifies the resource that was marked as a favorite.
	ResourceId *ResourceId `json:"resourceId,omitempty"`

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

// ActivityContentDetailsLike: Information about a resource that
// received a positive (like) rating.
type ActivityContentDetailsLike struct {
	// ResourceId: The resourceId object contains information that
	// identifies the rated resource.
	ResourceId *ResourceId `json:"resourceId,omitempty"`

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

// ActivityContentDetailsPlaylistItem: Information about a new playlist
// item.
type ActivityContentDetailsPlaylistItem struct {
	// PlaylistId: The value that YouTube uses to uniquely identify the
	// playlist.
	PlaylistId string `json:"playlistId,omitempty"`

	// PlaylistItemId: ID of the item within the playlist.
	PlaylistItemId string `json:"playlistItemId,omitempty"`

	// ResourceId: The resourceId object contains information about the
	// resource that was added to the playlist.
	ResourceId *ResourceId `json:"resourceId,omitempty"`

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

// ActivityContentDetailsPromotedItem: Details about a resource which is
// being promoted.
type ActivityContentDetailsPromotedItem struct {
	// AdTag: The URL the client should fetch to request a promoted item.
	AdTag string `json:"adTag,omitempty"`

	// ClickTrackingUrl: The URL the client should ping to indicate that the
	// user clicked through on this promoted item.
	ClickTrackingUrl string `json:"clickTrackingUrl,omitempty"`

	// CreativeViewUrl: The URL the client should ping to indicate that the
	// user was shown this promoted item.
	CreativeViewUrl string `json:"creativeViewUrl,omitempty"`

	// CtaType: The type of call-to-action, a message to the user indicating
	// action that can be taken.
	//
	// Possible values:
	//   "ctaTypeUnspecified"
	//   "visitAdvertiserSite"
	CtaType string `json:"ctaType,omitempty"`

	// CustomCtaButtonText: The custom call-to-action button text. If
	// specified, it will override the default button text for the cta_type.
	CustomCtaButtonText string `json:"customCtaButtonText,omitempty"`

	// DescriptionText: The text description to accompany the promoted item.
	DescriptionText string `json:"descriptionText,omitempty"`

	// DestinationUrl: The URL the client should direct the user to, if the
	// user chooses to visit the advertiser's website.
	DestinationUrl string `json:"destinationUrl,omitempty"`

	// ForecastingUrl: The list of forecasting URLs. The client should ping
	// all of these URLs when a promoted item is not available, to indicate
	// that a promoted item could have been shown.
	ForecastingUrl []string `json:"forecastingUrl,omitempty"`

	// ImpressionUrl: The list of impression URLs. The client should ping
	// all of these URLs to indicate that the user was shown this promoted
	// item.
	ImpressionUrl []string `json:"impressionUrl,omitempty"`

	// VideoId: The ID that YouTube uses to uniquely identify the promoted
	// video.
	VideoId string `json:"videoId,omitempty"`

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

// ActivityContentDetailsRecommendation: Information that identifies the
// recommended resource.
type ActivityContentDetailsRecommendation struct {
	// Reason: The reason that the resource is recommended to the user.
	//
	// Possible values:
	//   "reasonUnspecified"
	//   "videoFavorited"
	//   "videoLiked"
	//   "videoWatched"
	Reason string `json:"reason,omitempty"`

	// ResourceId: The resourceId object contains information that
	// identifies the recommended resource.
	ResourceId *ResourceId `json:"resourceId,omitempty"`

	// SeedResourceId: The seedResourceId object contains information about
	// the resource that caused the recommendation.
	SeedResourceId *ResourceId `json:"seedResourceId,omitempty"`

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

// ActivityContentDetailsSocial: Details about a social network post.
type ActivityContentDetailsSocial struct {
	// Author: The author of the social network post.
	Author string `json:"author,omitempty"`

	// ImageUrl: An image of the post's author.
	ImageUrl string `json:"imageUrl,omitempty"`

	// ReferenceUrl: The URL of the social network post.
	ReferenceUrl string `json:"referenceUrl,omitempty"`

	// ResourceId: The resourceId object encapsulates information that
	// identifies the resource associated with a social network post.
	ResourceId *ResourceId `json:"resourceId,omitempty"`

	// Type: The name of the social network.
	//
	// Possible values:
	//   "typeUnspecified"
	//   "googlePlus"
	//   "facebook"
	//   "twitter"
	Type string `json:"type,omitempty"`

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

// ActivityContentDetailsSubscription: Information about a channel that
// a user subscribed to.
type ActivityContentDetailsSubscription struct {
	// ResourceId: The resourceId object contains information that
	// identifies the resource that the user subscribed to.
	ResourceId *ResourceId `json:"resourceId,omitempty"`

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

// ActivityContentDetailsUpload: Information about the uploaded video.
type ActivityContentDetailsUpload struct {
	// VideoId: The ID that YouTube uses to uniquely identify the uploaded
	// video.
	VideoId string `json:"videoId,omitempty"`

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

type ActivityListResponse struct {
	// Etag: Etag of this resource.
	Etag string `json:"etag,omitempty"`

	// EventId: Serialized EventId of the request which produced this
	// response.
	EventId string `json:"eventId,omitempty"`

	Items []*Activity `json:"items,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "youtube#activityListResponse".
	Kind string `json:"kind,omitempty"`

	// NextPageToken: The token that can be used as the value of the
	// pageToken parameter to retrieve the next page in the result set.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// PageInfo: General pagination information.
	PageInfo *PageInfo `json:"pageInfo,omitempty"`

	// PrevPageToken: The token that can be used as the value of the
	// pageToken parameter to retrieve the previous page in the result set.
	PrevPageToken string `json:"prevPageToken,omitempty"`

	TokenPagination *TokenPagination `json:"tokenPagination,omitempty"`

	// VisitorId: The visitorId identifies the visitor.
	VisitorId string `json:"visitorId,omitempty"`

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

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

// ActivitySnippet: Basic details about an activity, including title,
// description, thumbnails, activity type and group. Next ID: 12
type ActivitySnippet struct {
	// ChannelId: The ID that YouTube uses to uniquely identify the channel
	// associated with the activity.
	ChannelId string `json:"channelId,omitempty"`

	// ChannelTitle: Channel title for the channel responsible for this
	// activity
	ChannelTitle string `json:"channelTitle,omitempty"`

	// Description: The description of the resource primarily associated
	// with the activity. @mutable youtube.activities.insert
	Description string `json:"description,omitempty"`

	// GroupId: The group ID associated with the activity. A group ID
	// identifies user events that are associated with the same user and
	// resource. For example, if a user rates a video and marks the same
	// video as a favorite, the entries for those events would have the same
	// group ID in the user's activity feed. In your user interface, you can
	// avoid repetition by grouping events with the same groupId value.
	GroupId string `json:"groupId,omitempty"`

	// PublishedAt: The date and time that the video was uploaded. The value
	// is specified in ISO 8601 format.
	PublishedAt string `json:"publishedAt,omitempty"`

	// Thumbnails: A map of thumbnail images associated with the resource
	// that is primarily associated with the activity. For each object in
	// the map, the key is the name of the thumbnail image, and the value is
	// an object that contains other information about the thumbnail.
	Thumbnails *ThumbnailDetails `json:"thumbnails,omitempty"`

	// Title: The title of the resource primarily associated with the
	// activity.
	Title string `json:"title,omitempty"`

	// Type: The type of activity that the resource describes.
	//
	// Possible values:
	//   "typeUnspecified"
	//   "upload"
	//   "like"
	//   "favorite"
	//   "comment"
	//   "subscription"
	//   "playlistItem"
	//   "recommendation"
	//   "bulletin"
	//   "social"
	//   "channelItem"
	//   "promotedItem"
	Type string `json:"type,omitempty"`

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

// Caption: A *caption* resource represents a YouTube caption track. A
// caption track is associated with exactly one YouTube video.
type Caption struct {
	// Etag: Etag of this resource.
	Etag string `json:"etag,omitempty"`

	// Id: The ID that YouTube uses to uniquely identify the caption track.
	Id string `json:"id,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "youtube#caption".
	Kind string `json:"kind,omitempty"`

	// Snippet: The snippet object contains basic details about the caption.
	Snippet *CaptionSnippet `json:"snippet,omitempty"`

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

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

type CaptionListResponse struct {
	// Etag: Etag of this resource.
	Etag string `json:"etag,omitempty"`

	// EventId: Serialized EventId of the request which produced this
	// response.
	EventId string `json:"eventId,omitempty"`

	// Items: A list of captions that match the request criteria.
	Items []*Caption `json:"items,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "youtube#captionListResponse".
	Kind string `json:"kind,omitempty"`

	// VisitorId: The visitorId identifies the visitor.
	VisitorId string `json:"visitorId,omitempty"`

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

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

// CaptionSnippet: Basic details about a caption track, such as its
// language and name.
type CaptionSnippet struct {
	// AudioTrackType: The type of audio track associated with the caption
	// track.
	//
	// Possible values:
	//   "unknown"
	//   "primary"
	//   "commentary"
	//   "descriptive"
	AudioTrackType string `json:"audioTrackType,omitempty"`

	// FailureReason: The reason that YouTube failed to process the caption
	// track. This property is only present if the state property's value is
	// failed.
	//
	// Possible values:
	//   "unknownFormat"
	//   "unsupportedFormat"
	//   "processingFailed"
	FailureReason string `json:"failureReason,omitempty"`

	// IsAutoSynced: Indicates whether YouTube synchronized the caption
	// track to the audio track in the video. The value will be true if a
	// sync was explicitly requested when the caption track was uploaded.
	// For example, when calling the captions.insert or captions.update
	// methods, you can set the sync parameter to true to instruct YouTube
	// to sync the uploaded track to the video. If the value is false,
	// YouTube uses the time codes in the uploaded caption track to
	// determine when to display captions.
	IsAutoSynced bool `json:"isAutoSynced,omitempty"`

	// IsCC: Indicates whether the track contains closed captions for the
	// deaf and hard of hearing. The default value is false.
	IsCC bool `json:"isCC,omitempty"`

	// IsDraft: Indicates whether the caption track is a draft. If the value
	// is true, then the track is not publicly visible. The default value is
	// false. @mutable youtube.captions.insert youtube.captions.update
	IsDraft bool `json:"isDraft,omitempty"`

	// IsEasyReader: Indicates whether caption track is formatted for "easy
	// reader," meaning it is at a third-grade level for language learners.
	// The default value is false.
	IsEasyReader bool `json:"isEasyReader,omitempty"`

	// IsLarge: Indicates whether the caption track uses large text for the
	// vision-impaired. The default value is false.
	IsLarge bool `json:"isLarge,omitempty"`

	// Language: The language of the caption track. The property value is a
	// BCP-47 language tag.
	Language string `json:"language,omitempty"`

	// LastUpdated: The date and time when the caption track was last
	// updated. The value is specified in ISO 8601 format.
	LastUpdated string `json:"lastUpdated,omitempty"`

	// Name: The name of the caption track. The name is intended to be
	// visible to the user as an option during playback.
	Name string `json:"name,omitempty"`

	// Status: The caption track's status.
	//
	// Possible values:
	//   "serving"
	//   "syncing"
	//   "failed"
	Status string `json:"status,omitempty"`

	// TrackKind: The caption track's type.
	//
	// Possible values:
	//   "standard"
	//   "ASR"
	//   "forced"
	TrackKind string `json:"trackKind,omitempty"`

	// VideoId: The ID that YouTube uses to uniquely identify the video
	// associated with the caption track. @mutable youtube.captions.insert
	VideoId string `json:"videoId,omitempty"`

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

// CdnSettings: Brief description of the live stream cdn settings.
type CdnSettings struct {
	// Format: The format of the video stream that you are sending to
	// Youtube.
	Format string `json:"format,omitempty"`

	// FrameRate: The frame rate of the inbound video data.
	//
	// Possible values:
	//   "30fps"
	//   "60fps"
	//   "variable"
	FrameRate string `json:"frameRate,omitempty"`

	// IngestionInfo: The ingestionInfo object contains information that
	// YouTube provides that you need to transmit your RTMP or HTTP stream
	// to YouTube.
	IngestionInfo *IngestionInfo `json:"ingestionInfo,omitempty"`

	// IngestionType:  The method or protocol used to transmit the video
	// stream.
	//
	// Possible values:
	//   "rtmp"
	//   "dash"
	//   "webrtc"
	//   "hls"
	IngestionType string `json:"ingestionType,omitempty"`

	// Resolution: The resolution of the inbound video data.
	//
	// Possible values:
	//   "240p"
	//   "360p"
	//   "480p"
	//   "720p"
	//   "1080p"
	//   "1440p"
	//   "2160p"
	//   "variable"
	Resolution string `json:"resolution,omitempty"`

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

// Channel: A *channel* resource contains information about a YouTube
// channel.
type Channel struct {
	// AuditDetails: The auditionDetails object encapsulates channel data
	// that is relevant for YouTube Partners during the audition process.
	AuditDetails *ChannelAuditDetails `json:"auditDetails,omitempty"`

	// BrandingSettings: The brandingSettings object encapsulates
	// information about the branding of the channel.
	BrandingSettings *ChannelBrandingSettings `json:"brandingSettings,omitempty"`

	// ContentDetails: The contentDetails object encapsulates information
	// about the channel's content.
	ContentDetails *ChannelContentDetails `json:"contentDetails,omitempty"`

	// ContentOwnerDetails: The contentOwnerDetails object encapsulates
	// channel data that is relevant for YouTube Partners linked with the
	// channel.
	ContentOwnerDetails *ChannelContentOwnerDetails `json:"contentOwnerDetails,omitempty"`

	// ConversionPings: The conversionPings object encapsulates information
	// about conversion pings that need to be respected by the channel.
	ConversionPings *ChannelConversionPings `json:"conversionPings,omitempty"`

	// Etag: Etag of this resource.
	Etag string `json:"etag,omitempty"`

	// Id: The ID that YouTube uses to uniquely identify the channel.
	Id string `json:"id,omitempty"`

	// InvideoPromotion: The invideoPromotion object encapsulates
	// information about promotion campaign associated with the channel.
	InvideoPromotion *InvideoPromotion `json:"invideoPromotion,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "youtube#channel".
	Kind string `json:"kind,omitempty"`

	// Localizations: Localizations for different languages
	Localizations map[string]ChannelLocalization `json:"localizations,omitempty"`

	// Snippet: The snippet object contains basic details about the channel,
	// such as its title, description, and thumbnail images.
	Snippet *ChannelSnippet `json:"snippet,omitempty"`

	// Statistics: The statistics object encapsulates statistics for the
	// channel.
	Statistics *ChannelStatistics `json:"statistics,omitempty"`

	// Status: The status object encapsulates information about the privacy
	// status of the channel.
	Status *ChannelStatus `json:"status,omitempty"`

	// TopicDetails: The topicDetails object encapsulates information about
	// Freebase topics associated with the channel.
	TopicDetails *ChannelTopicDetails `json:"topicDetails,omitempty"`

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

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

// ChannelAuditDetails: The auditDetails object encapsulates channel
// data that is relevant for YouTube Partners during the audit process.
type ChannelAuditDetails struct {
	// CommunityGuidelinesGoodStanding: Whether or not the channel respects
	// the community guidelines.
	CommunityGuidelinesGoodStanding bool `json:"communityGuidelinesGoodStanding,omitempty"`

	// ContentIdClaimsGoodStanding: Whether or not the channel has any
	// unresolved claims.
	ContentIdClaimsGoodStanding bool `json:"contentIdClaimsGoodStanding,omitempty"`

	// CopyrightStrikesGoodStanding: Whether or not the channel has any
	// copyright strikes.
	CopyrightStrikesGoodStanding bool `json:"copyrightStrikesGoodStanding,omitempty"`

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

// ChannelBannerResource: A channel banner returned as the response to a
// channel_banner.insert call.
type ChannelBannerResource struct {
	Etag string `json:"etag,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "youtube#channelBannerResource".
	Kind string `json:"kind,omitempty"`

	// Url: The URL of this banner image.
	Url string `json:"url,omitempty"`

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

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

// ChannelBrandingSettings: Branding properties of a YouTube channel.
type ChannelBrandingSettings struct {
	// Channel: Branding properties for the channel view.
	Channel *ChannelSettings `json:"channel,omitempty"`

	// Hints: Additional experimental branding properties.
	Hints []*PropertyValue `json:"hints,omitempty"`

	// Image: Branding properties for branding images.
	Image *ImageSettings `json:"image,omitempty"`

	// Watch: Branding properties for the watch page.
	Watch *WatchSettings `json:"watch,omitempty"`

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

// ChannelContentDetails: Details about the content of a channel.
type ChannelContentDetails struct {
	RelatedPlaylists *ChannelContentDetailsRelatedPlaylists `json:"relatedPlaylists,omitempty"`

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

type ChannelContentDetailsRelatedPlaylists struct {
	// Favorites: The ID of the playlist that contains the channel"s
	// favorite videos. Use the playlistItems.insert and
	// playlistItems.delete to add or remove items from that list.
	Favorites string `json:"favorites,omitempty"`

	// Likes: The ID of the playlist that contains the channel"s liked
	// videos. Use the playlistItems.insert and playlistItems.delete to add
	// or remove items from that list.
	Likes string `json:"likes,omitempty"`

	// Uploads: The ID of the playlist that contains the channel"s uploaded
	// videos. Use the videos.insert method to upload new videos and the
	// videos.delete method to delete previously uploaded videos.
	Uploads string `json:"uploads,omitempty"`

	// WatchHistory: The ID of the playlist that contains the channel"s
	// watch history. Use the playlistItems.insert and playlistItems.delete
	// to add or remove items from that list.
	WatchHistory string `json:"watchHistory,omitempty"`

	// WatchLater: The ID of the playlist that contains the channel"s watch
	// later playlist. Use the playlistItems.insert and playlistItems.delete
	// to add or remove items from that list.
	WatchLater string `json:"watchLater,omitempty"`

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

// ChannelContentOwnerDetails: The contentOwnerDetails object
// encapsulates channel data that is relevant for YouTube Partners
// linked with the channel.
type ChannelContentOwnerDetails struct {
	// ContentOwner: The ID of the content owner linked to the channel.
	ContentOwner string `json:"contentOwner,omitempty"`

	// TimeLinked: The date and time of when the channel was linked to the
	// content owner. The value is specified in ISO 8601 format.
	TimeLinked string `json:"timeLinked,omitempty"`

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

// ChannelConversionPing: Pings that the app shall fire (authenticated
// by biscotti cookie). Each ping has a context, in which the app must
// fire the ping, and a url identifying the ping.
type ChannelConversionPing struct {
	// Context: Defines the context of the ping.
	//
	// Possible values:
	//   "subscribe"
	//   "unsubscribe"
	//   "cview"
	Context string `json:"context,omitempty"`

	// ConversionUrl: The url (without the schema) that the player shall
	// send the ping to. It's at caller's descretion to decide which schema
	// to use (http vs https) Example of a returned url:
	// //googleads.g.doubleclick.net/pagead/
	// viewthroughconversion/962985656/?data=path%3DtHe_path%3Btype%3D
	// cview%3Butuid%3DGISQtTNGYqaYl4sKxoVvKA&labe=default The caller must
	// append biscotti authentication (ms param in case of mobile, for
	// example) to this ping.
	ConversionUrl string `json:"conversionUrl,omitempty"`

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

// ChannelConversionPings: The conversionPings object encapsulates
// information about conversion pings that need to be respected by the
// channel.
type ChannelConversionPings struct {
	// Pings: Pings that the app shall fire (authenticated by biscotti
	// cookie). Each ping has a context, in which the app must fire the
	// ping, and a url identifying the ping.
	Pings []*ChannelConversionPing `json:"pings,omitempty"`

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

type ChannelListResponse struct {
	// Etag: Etag of this resource.
	Etag string `json:"etag,omitempty"`

	// EventId: Serialized EventId of the request which produced this
	// response.
	EventId string `json:"eventId,omitempty"`

	Items []*Channel `json:"items,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "youtube#channelListResponse".
	Kind string `json:"kind,omitempty"`

	// NextPageToken: The token that can be used as the value of the
	// pageToken parameter to retrieve the next page in the result set.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// PageInfo: General pagination information.
	PageInfo *PageInfo `json:"pageInfo,omitempty"`

	// PrevPageToken: The token that can be used as the value of the
	// pageToken parameter to retrieve the previous page in the result set.
	PrevPageToken string `json:"prevPageToken,omitempty"`

	TokenPagination *TokenPagination `json:"tokenPagination,omitempty"`

	// VisitorId: The visitorId identifies the visitor.
	VisitorId string `json:"visitorId,omitempty"`

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

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

// ChannelLocalization: Channel localization setting
type ChannelLocalization struct {
	// Description: The localized strings for channel's description.
	Description string `json:"description,omitempty"`

	// Title: The localized strings for channel's title.
	Title string `json:"title,omitempty"`

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

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

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

type ChannelProfileDetails struct {
	// ChannelId: The YouTube channel ID.
	ChannelId string `json:"channelId,omitempty"`

	// ChannelUrl: The channel's URL.
	ChannelUrl string `json:"channelUrl,omitempty"`

	// DisplayName: The channel's display name.
	DisplayName string `json:"displayName,omitempty"`

	// ProfileImageUrl: The channels's avatar URL.
	ProfileImageUrl string `json:"profileImageUrl,omitempty"`

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

type ChannelSection struct {
	// ContentDetails: The contentDetails object contains details about the
	// channel section content, such as a list of playlists or channels
	// featured in the section.
	ContentDetails *ChannelSectionContentDetails `json:"contentDetails,omitempty"`

	// Etag: Etag of this resource.
	Etag string `json:"etag,omitempty"`

	// Id: The ID that YouTube uses to uniquely identify the channel
	// section.
	Id string `json:"id,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "youtube#channelSection".
	Kind string `json:"kind,omitempty"`

	// Localizations: Localizations for different languages
	Localizations map[string]ChannelSectionLocalization `json:"localizations,omitempty"`

	// Snippet: The snippet object contains basic details about the channel
	// section, such as its type, style and title.
	Snippet *ChannelSectionSnippet `json:"snippet,omitempty"`

	// Targeting: The targeting object contains basic targeting settings
	// about the channel section.
	Targeting *ChannelSectionTargeting `json:"targeting,omitempty"`

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

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

// ChannelSectionContentDetails: Details about a channelsection,
// including playlists and channels.
type ChannelSectionContentDetails struct {
	// Channels: The channel ids for type multiple_channels.
	Channels []string `json:"channels,omitempty"`

	// Playlists: The playlist ids for type single_playlist and
	// multiple_playlists. For singlePlaylist, only one playlistId is
	// allowed.
	Playlists []string `json:"playlists,omitempty"`

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

type ChannelSectionListResponse struct {
	// Etag: Etag of this resource.
	Etag string `json:"etag,omitempty"`

	// EventId: Serialized EventId of the request which produced this
	// response.
	EventId string `json:"eventId,omitempty"`

	// Items: A list of ChannelSections that match the request criteria.
	Items []*ChannelSection `json:"items,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "youtube#channelSectionListResponse".
	Kind string `json:"kind,omitempty"`

	// VisitorId: The visitorId identifies the visitor.
	VisitorId string `json:"visitorId,omitempty"`

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

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

// ChannelSectionLocalization: ChannelSection localization setting
type ChannelSectionLocalization struct {
	// Title: The localized strings for channel section's title.
	Title string `json:"title,omitempty"`

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

// ChannelSectionSnippet: Basic details about a channel section,
// including title, style and position.
type ChannelSectionSnippet struct {
	// ChannelId: The ID that YouTube uses to uniquely identify the channel
	// that published the channel section.
	ChannelId string `json:"channelId,omitempty"`

	// DefaultLanguage: The language of the channel section's default title
	// and description.
	DefaultLanguage string `json:"defaultLanguage,omitempty"`

	// Localized: Localized title, read-only.
	Localized *ChannelSectionLocalization `json:"localized,omitempty"`

	// Position: The position of the channel section in the channel.
	Position *int64 `json:"position,omitempty"`

	// Style: The style of the channel section.
	//
	// Possible values:
	//   "channelsectionStyleUnspecified"
	//   "horizontalRow"
	//   "verticalList"
	Style string `json:"style,omitempty"`

	// Title: The channel section's title for multiple_playlists and
	// multiple_channels.
	Title string `json:"title,omitempty"`

	// Type: The type of the channel section.
	//
	// Possible values:
	//   "channelsectionTypeUnspecified"
	//   "singlePlaylist"
	//   "multiplePlaylists"
	//   "popularUploads"
	//   "recentUploads"
	//   "likes"
	//   "allPlaylists"
	//   "likedPlaylists"
	//   "recentPosts"
	//   "recentActivity"
	//   "liveEvents"
	//   "upcomingEvents"
	//   "completedEvents"
	//   "multipleChannels"
	//   "postedVideos"
	//   "postedPlaylists"
	//   "subscriptions"
	Type string `json:"type,omitempty"`

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

// ChannelSectionTargeting: ChannelSection targeting setting.
type ChannelSectionTargeting struct {
	// Countries: The country the channel section is targeting.
	Countries []string `json:"countries,omitempty"`

	// Languages: The language the channel section is targeting.
	Languages []string `json:"languages,omitempty"`

	// Regions: The region the channel section is targeting.
	Regions []string `json:"regions,omitempty"`

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

// ChannelSettings: Branding properties for the channel view.
type ChannelSettings struct {
	// Country: The country of the channel.
	Country string `json:"country,omitempty"`

	DefaultLanguage string `json:"defaultLanguage,omitempty"`

	// DefaultTab: Which content tab users should see when viewing the
	// channel.
	DefaultTab string `json:"defaultTab,omitempty"`

	// Description: Specifies the channel description.
	Description string `json:"description,omitempty"`

	// FeaturedChannelsTitle: Title for the featured channels tab.
	FeaturedChannelsTitle string `json:"featuredChannelsTitle,omitempty"`

	// FeaturedChannelsUrls: The list of featured channels.
	FeaturedChannelsUrls []string `json:"featuredChannelsUrls,omitempty"`

	// Keywords: Lists keywords associated with the channel,
	// comma-separated.
	Keywords string `json:"keywords,omitempty"`

	// ModerateComments: Whether user-submitted comments left on the channel
	// page need to be approved by the channel owner to be publicly visible.
	ModerateComments bool `json:"moderateComments,omitempty"`

	// ProfileColor: A prominent color that can be rendered on this channel
	// page.
	ProfileColor string `json:"profileColor,omitempty"`

	// ShowBrowseView: Whether the tab to browse the videos should be
	// displayed.
	ShowBrowseView bool `json:"showBrowseView,omitempty"`

	// ShowRelatedChannels: Whether related channels should be proposed.
	ShowRelatedChannels bool `json:"showRelatedChannels,omitempty"`

	// Title: Specifies the channel title.
	Title string `json:"title,omitempty"`

	// TrackingAnalyticsAccountId: The ID for a Google Analytics account to
	// track and measure traffic to the channels.
	TrackingAnalyticsAccountId string `json:"trackingAnalyticsAccountId,omitempty"`

	// UnsubscribedTrailer: The trailer of the channel, for users that are
	// not subscribers.
	UnsubscribedTrailer string `json:"unsubscribedTrailer,omitempty"`

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

// ChannelSnippet: Basic details about a channel, including title,
// description and thumbnails.
type ChannelSnippet struct {
	// Country: The country of the channel.
	Country string `json:"country,omitempty"`

	// CustomUrl: The custom url of the channel.
	CustomUrl string `json:"customUrl,omitempty"`

	// DefaultLanguage: The language of the channel's default title and
	// description.
	DefaultLanguage string `json:"defaultLanguage,omitempty"`

	// Description: The description of the channel.
	Description string `json:"description,omitempty"`

	// Localized: Localized title and description, read-only.
	Localized *ChannelLocalization `json:"localized,omitempty"`

	// PublishedAt: The date and time that the channel was created. The
	// value is specified in < a href="//www.w3.org/TR/NOTE-datetime">ISO
	// 8601 format.
	PublishedAt string `json:"publishedAt,omitempty"`

	// Thumbnails: A map of thumbnail images associated with the channel.
	// For each object in the map, the key is the name of the thumbnail
	// image, and the value is an object that contains other information
	// about the thumbnail. When displaying thumbnails in your application,
	// make sure that your code uses the image URLs exactly as they are
	// returned in API responses. For example, your application should not
	// use the http domain instead of the https domain in a URL returned in
	// an API response. Beginning in July 2018, channel thumbnail URLs will
	// only be available in the https domain, which is how the URLs appear
	// in API responses. After that time, you might see broken images in
	// your application if it tries to load YouTube images from the http
	// domain.
	Thumbnails *ThumbnailDetails `json:"thumbnails,omitempty"`

	// Title: The channel's title.
	Title string `json:"title,omitempty"`

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

// ChannelStatistics: Statistics about a channel: number of subscribers,
// number of videos in the channel, etc.
type ChannelStatistics struct {
	// CommentCount: The number of comments for the channel.
	CommentCount uint64 `json:"commentCount,omitempty,string"`

	// HiddenSubscriberCount: Whether or not the number of subscribers is
	// shown for this user.
	HiddenSubscriberCount bool `json:"hiddenSubscriberCount,omitempty"`

	// SubscriberCount: The number of subscribers that the channel has.
	SubscriberCount uint64 `json:"subscriberCount,omitempty,string"`

	// VideoCount: The number of videos uploaded to the channel.
	VideoCount uint64 `json:"videoCount,omitempty,string"`

	// ViewCount: The number of times the channel has been viewed.
	ViewCount uint64 `json:"viewCount,omitempty,string"`

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

// ChannelStatus: JSON template for the status part of a channel.
type ChannelStatus struct {
	// IsLinked: If true, then the user is linked to either a YouTube
	// username or G+ account. Otherwise, the user doesn't have a public
	// YouTube identity.
	IsLinked bool `json:"isLinked,omitempty"`

	// LongUploadsStatus: The long uploads status of this channel. See
	// https://support.google.com/youtube/answer/71673 for more information.
	//
	// Possible values:
	//   "longUploadsUnspecified"
	//   "allowed"
	//   "eligible"
	//   "disallowed"
	LongUploadsStatus string `json:"longUploadsStatus,omitempty"`

	MadeForKids bool `json:"madeForKids,omitempty"`

	// PrivacyStatus: Privacy status of the channel.
	//
	// Possible values:
	//   "public"
	//   "unlisted"
	//   "private"
	PrivacyStatus string `json:"privacyStatus,omitempty"`

	SelfDeclaredMadeForKids bool `json:"selfDeclaredMadeForKids,omitempty"`

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

// ChannelToStoreLinkDetails: Information specific to a store on a
// merchandising platform linked to a YouTube channel.
type ChannelToStoreLinkDetails struct {
	// StoreName: Name of the store.
	StoreName string `json:"storeName,omitempty"`

	// StoreUrl: Landing page of the store.
	StoreUrl string `json:"storeUrl,omitempty"`

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

// ChannelTopicDetails: Freebase topic information related to the
// channel.
type ChannelTopicDetails struct {
	// TopicCategories: A list of Wikipedia URLs that describe the channel's
	// content.
	TopicCategories []string `json:"topicCategories,omitempty"`

	// TopicIds: A list of Freebase topic IDs associated with the channel.
	// You can retrieve information about each topic using the Freebase
	// Topic API.
	TopicIds []string `json:"topicIds,omitempty"`

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

// Comment: A *comment* represents a single YouTube comment.
type Comment struct {
	// Etag: Etag of this resource.
	Etag string `json:"etag,omitempty"`

	// Id: The ID that YouTube uses to uniquely identify the comment.
	Id string `json:"id,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "youtube#comment".
	Kind string `json:"kind,omitempty"`

	// Snippet: The snippet object contains basic details about the comment.
	Snippet *CommentSnippet `json:"snippet,omitempty"`

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

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

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

type CommentListResponse struct {
	// Etag: Etag of this resource.
	Etag string `json:"etag,omitempty"`

	// EventId: Serialized EventId of the request which produced this
	// response.
	EventId string `json:"eventId,omitempty"`

	// Items: A list of comments that match the request criteria.
	Items []*Comment `json:"items,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "youtube#commentListResponse".
	Kind string `json:"kind,omitempty"`

	// NextPageToken: The token that can be used as the value of the
	// pageToken parameter to retrieve the next page in the result set.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// PageInfo: General pagination information.
	PageInfo *PageInfo `json:"pageInfo,omitempty"`

	TokenPagination *TokenPagination `json:"tokenPagination,omitempty"`

	// VisitorId: The visitorId identifies the visitor.
	VisitorId string `json:"visitorId,omitempty"`

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

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

// CommentSnippet: Basic details about a comment, such as its author and
// text.
type CommentSnippet struct {
	AuthorChannelId *CommentSnippetAuthorChannelId `json:"authorChannelId,omitempty"`

	// AuthorChannelUrl: Link to the author's YouTube channel, if any.
	AuthorChannelUrl string `json:"authorChannelUrl,omitempty"`

	// AuthorDisplayName: The name of the user who posted the comment.
	AuthorDisplayName string `json:"authorDisplayName,omitempty"`

	// AuthorProfileImageUrl: The URL for the avatar of the user who posted
	// the comment.
	AuthorProfileImageUrl string `json:"authorProfileImageUrl,omitempty"`

	// CanRate: Whether the current viewer can rate this comment.
	CanRate bool `json:"canRate,omitempty"`

	// ChannelId: The id of the corresponding YouTube channel. In case of a
	// channel comment this is the channel the comment refers to. In case of
	// a video comment it's the video's channel.
	ChannelId string `json:"channelId,omitempty"`

	// LikeCount: The total number of likes this comment has received.
	LikeCount int64 `json:"likeCount,omitempty"`

	// ModerationStatus: The comment's moderation status. Will not be set if
	// the comments were requested through the id filter.
	//
	// Possible values:
	//   "published"
	//   "heldForReview"
	//   "likelySpam"
	//   "rejected"
	ModerationStatus string `json:"moderationStatus,omitempty"`

	// ParentId: The unique id of the parent comment, only set for replies.
	ParentId string `json:"parentId,omitempty"`

	// PublishedAt: The date and time when the comment was orignally
	// published. The value is specified in ISO 8601 format.
	PublishedAt string `json:"publishedAt,omitempty"`

	// TextDisplay: The comment's text. The format is either plain text or
	// HTML dependent on what has been requested. Even the plain text
	// representation may differ from the text originally posted in that it
	// may replace video links with video titles etc.
	TextDisplay string `json:"textDisplay,omitempty"`

	// TextOriginal: The comment's original raw text as initially posted or
	// last updated. The original text will only be returned if it is
	// accessible to the viewer, which is only guaranteed if the viewer is
	// the comment's author.
	TextOriginal string `json:"textOriginal,omitempty"`

	// UpdatedAt: The date and time when was last updated . The value is
	// specified in ISO 8601 format.
	UpdatedAt string `json:"updatedAt,omitempty"`

	// VideoId: The ID of the video the comment refers to, if any.
	VideoId string `json:"videoId,omitempty"`

	// ViewerRating: The rating the viewer has given to this comment. For
	// the time being this will never return RATE_TYPE_DISLIKE and instead
	// return RATE_TYPE_NONE. This may change in the future.
	//
	// Possible values:
	//   "none"
	//   "like"
	//   "dislike"
	ViewerRating string `json:"viewerRating,omitempty"`

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

// CommentSnippetAuthorChannelId: The id of the author's YouTube
// channel, if any.
type CommentSnippetAuthorChannelId struct {
	Value string `json:"value,omitempty"`

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

// CommentThread: A *comment thread* represents information that applies
// to a top level comment and all its replies. It can also include the
// top level comment itself and some of the replies.
type CommentThread struct {
	// Etag: Etag of this resource.
	Etag string `json:"etag,omitempty"`

	// Id: The ID that YouTube uses to uniquely identify the comment thread.
	Id string `json:"id,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "youtube#commentThread".
	Kind string `json:"kind,omitempty"`

	// Replies: The replies object contains a limited number of replies (if
	// any) to the top level comment found in the snippet.
	Replies *CommentThreadReplies `json:"replies,omitempty"`

	// Snippet: The snippet object contains basic details about the comment
	// thread and also the top level comment.
	Snippet *CommentThreadSnippet `json:"snippet,omitempty"`

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

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

type CommentThreadListResponse struct {
	// Etag: Etag of this resource.
	Etag string `json:"etag,omitempty"`

	// EventId: Serialized EventId of the request which produced this
	// response.
	EventId string `json:"eventId,omitempty"`

	// Items: A list of comment threads that match the request criteria.
	Items []*CommentThread `json:"items,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "youtube#commentThreadListResponse".
	Kind string `json:"kind,omitempty"`

	// NextPageToken: The token that can be used as the value of the
	// pageToken parameter to retrieve the next page in the result set.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// PageInfo: General pagination information.
	PageInfo *PageInfo `json:"pageInfo,omitempty"`

	TokenPagination *TokenPagination `json:"tokenPagination,omitempty"`

	// VisitorId: The visitorId identifies the visitor.
	VisitorId string `json:"visitorId,omitempty"`

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

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

// CommentThreadReplies: Comments written in (direct or indirect) reply
// to the top level comment.
type CommentThreadReplies struct {
	// Comments: A limited number of replies. Unless the number of replies
	// returned equals total_reply_count in the snippet the returned replies
	// are only a subset of the total number of replies.
	Comments []*Comment `json:"comments,omitempty"`

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

// CommentThreadSnippet: Basic details about a comment thread.
type CommentThreadSnippet struct {
	// CanReply: Whether the current viewer of the thread can reply to it.
	// This is viewer specific - other viewers may see a different value for
	// this field.
	CanReply bool `json:"canReply,omitempty"`

	// ChannelId: The YouTube channel the comments in the thread refer to or
	// the channel with the video the comments refer to. If video_id isn't
	// set the comments refer to the channel itself.
	ChannelId string `json:"channelId,omitempty"`

	// IsPublic: Whether the thread (and therefore all its comments) is
	// visible to all YouTube users.
	IsPublic bool `json:"isPublic,omitempty"`

	// TopLevelComment: The top level comment of this thread.
	TopLevelComment *Comment `json:"topLevelComment,omitempty"`

	// TotalReplyCount: The total number of replies (not including the top
	// level comment).
	TotalReplyCount int64 `json:"totalReplyCount,omitempty"`

	// VideoId: The ID of the video the comments refer to, if any. No
	// video_id implies a channel discussion comment.
	VideoId string `json:"videoId,omitempty"`

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

// ContentRating: Ratings schemes. The country-specific ratings are
// mostly for movies and shows. LINT.IfChange
type ContentRating struct {
	// AcbRating: The video's Australian Classification Board (ACB) or
	// Australian Communications and Media Authority (ACMA) rating. ACMA
	// ratings are used to classify children's television programming.
	//
	// Possible values:
	//   "acbUnspecified"
	//   "acbE" - E
	//   "acbP" - Programs that have been given a P classification by the
	// Australian Communications and Media Authority. These programs are
	// intended for preschool children.
	//   "acbC" - Programs that have been given a C classification by the
	// Australian Communications and Media Authority. These programs are
	// intended for children (other than preschool children) who are younger
	// than 14 years of age.
	//   "acbG" - G
	//   "acbPg" - PG
	//   "acbM" - M
	//   "acbMa15plus" - MA15+
	//   "acbR18plus" - R18+
	//   "acbUnrated"
	AcbRating string `json:"acbRating,omitempty"`

	// AgcomRating: The video's rating from Italy's Autorità per le
	// Garanzie nelle Comunicazioni (AGCOM).
	//
	// Possible values:
	//   "agcomUnspecified"
	//   "agcomT" - T
	//   "agcomVm14" - VM14
	//   "agcomVm18" - VM18
	//   "agcomUnrated"
	AgcomRating string `json:"agcomRating,omitempty"`

	// AnatelRating: The video's Anatel (Asociación Nacional de
	// Televisión) rating for Chilean television.
	//
	// Possible values:
	//   "anatelUnspecified"
	//   "anatelF" - F
	//   "anatelI" - I
	//   "anatelI7" - I-7
	//   "anatelI10" - I-10
	//   "anatelI12" - I-12
	//   "anatelR" - R
	//   "anatelA" - A
	//   "anatelUnrated"
	AnatelRating string `json:"anatelRating,omitempty"`

	// BbfcRating: The video's British Board of Film Classification (BBFC)
	// rating.
	//
	// Possible values:
	//   "bbfcUnspecified"
	//   "bbfcU" - U
	//   "bbfcPg" - PG
	//   "bbfc12a" - 12A
	//   "bbfc12" - 12
	//   "bbfc15" - 15
	//   "bbfc18" - 18
	//   "bbfcR18" - R18
	//   "bbfcUnrated"
	BbfcRating string `json:"bbfcRating,omitempty"`

	// BfvcRating: The video's rating from Thailand's Board of Film and
	// Video Censors.
	//
	// Possible values:
	//   "bfvcUnspecified"
	//   "bfvcG" - G
	//   "bfvcE" - E
	//   "bfvc13" - 13
	//   "bfvc15" - 15
	//   "bfvc18" - 18
	//   "bfvc20" - 20
	//   "bfvcB" - B
	//   "bfvcUnrated"
	BfvcRating string `json:"bfvcRating,omitempty"`

	// BmukkRating: The video's rating from the Austrian Board of Media
	// Classification (Bundesministerium für Unterricht, Kunst und Kultur).
	//
	// Possible values:
	//   "bmukkUnspecified"
	//   "bmukkAa" - Unrestricted
	//   "bmukk6" - 6+
	//   "bmukk8" - 8+
	//   "bmukk10" - 10+
	//   "bmukk12" - 12+
	//   "bmukk14" - 14+
	//   "bmukk16" - 16+
	//   "bmukkUnrated"
	BmukkRating string `json:"bmukkRating,omitempty"`

	// CatvRating: Rating system for Canadian TV - Canadian TV
	// Classification System The video's rating from the Canadian
	// Radio-Television and Telecommunications Commission (CRTC) for
	// Canadian English-language broadcasts. For more information, see the
	// Canadian Broadcast Standards Council website.
	//
	// Possible values:
	//   "catvUnspecified"
	//   "catvC" - C
	//   "catvC8" - C8
	//   "catvG" - G
	//   "catvPg" - PG
	//   "catv14plus" - 14+
	//   "catv18plus" - 18+
	//   "catvUnrated"
	//   "catvE"
	CatvRating string `json:"catvRating,omitempty"`

	// CatvfrRating: The video's rating from the Canadian Radio-Television
	// and Telecommunications Commission (CRTC) for Canadian French-language
	// broadcasts. For more information, see the Canadian Broadcast
	// Standards Council website.
	//
	// Possible values:
	//   "catvfrUnspecified"
	//   "catvfrG" - G
	//   "catvfr8plus" - 8+
	//   "catvfr13plus" - 13+
	//   "catvfr16plus" - 16+
	//   "catvfr18plus" - 18+
	//   "catvfrUnrated"
	//   "catvfrE"
	CatvfrRating string `json:"catvfrRating,omitempty"`

	// CbfcRating: The video's Central Board of Film Certification (CBFC -
	// India) rating.
	//
	// Possible values:
	//   "cbfcUnspecified"
	//   "cbfcU" - U
	//   "cbfcUA" - U/A
	//   "cbfcA" - A
	//   "cbfcS" - S
	//   "cbfcUnrated"
	CbfcRating string `json:"cbfcRating,omitempty"`

	// CccRating: The video's Consejo de Calificación Cinematográfica
	// (Chile) rating.
	//
	// Possible values:
	//   "cccUnspecified"
	//   "cccTe" - Todo espectador
	//   "ccc6" - 6+ - Inconveniente para menores de 7 años
	//   "ccc14" - 14+
	//   "ccc18" - 18+
	//   "ccc18v" - 18+ - contenido excesivamente violento
	//   "ccc18s" - 18+ - contenido pornográfico
	//   "cccUnrated"
	CccRating string `json:"cccRating,omitempty"`

	// CceRating: The video's rating from Portugal's Comissão de
	// Classificação de Espect´culos.
	//
	// Possible values:
	//   "cceUnspecified"
	//   "cceM4" - 4
	//   "cceM6" - 6
	//   "cceM12" - 12
	//   "cceM16" - 16
	//   "cceM18" - 18
	//   "cceUnrated"
	//   "cceM14" - 14
	CceRating string `json:"cceRating,omitempty"`

	// ChfilmRating: The video's rating in Switzerland.
	//
	// Possible values:
	//   "chfilmUnspecified"
	//   "chfilm0" - 0
	//   "chfilm6" - 6
	//   "chfilm12" - 12
	//   "chfilm16" - 16
	//   "chfilm18" - 18
	//   "chfilmUnrated"
	ChfilmRating string `json:"chfilmRating,omitempty"`

	// ChvrsRating: The video's Canadian Home Video Rating System (CHVRS)
	// rating.
	//
	// Possible values:
	//   "chvrsUnspecified"
	//   "chvrsG" - G
	//   "chvrsPg" - PG
	//   "chvrs14a" - 14A
	//   "chvrs18a" - 18A
	//   "chvrsR" - R
	//   "chvrsE" - E
	//   "chvrsUnrated"
	ChvrsRating string `json:"chvrsRating,omitempty"`

	// CicfRating: The video's rating from the Commission de Contrôle des
	// Films (Belgium).
	//
	// Possible values:
	//   "cicfUnspecified"
	//   "cicfE" - E
	//   "cicfKtEa" - KT/EA
	//   "cicfKntEna" - KNT/ENA
	//   "cicfUnrated"
	CicfRating string `json:"cicfRating,omitempty"`

	// CnaRating: The video's rating from Romania's CONSILIUL NATIONAL AL
	// AUDIOVIZUALULUI (CNA).
	//
	// Possible values:
	//   "cnaUnspecified"
	//   "cnaAp" - AP
	//   "cna12" - 12
	//   "cna15" - 15
	//   "cna18" - 18
	//   "cna18plus" - 18+
	//   "cnaUnrated"
	CnaRating string `json:"cnaRating,omitempty"`

	// CncRating: Rating system in France - Commission de classification
	// cinematographique
	//
	// Possible values:
	//   "cncUnspecified"
	//   "cncT" - T
	//   "cnc10" - 10
	//   "cnc12" - 12
	//   "cnc16" - 16
	//   "cnc18" - 18
	//   "cncE" - E
	//   "cncInterdiction" - interdiction
	//   "cncUnrated"
	CncRating string `json:"cncRating,omitempty"`

	// CsaRating: The video's rating from France's Conseil supérieur de
	// l’audiovisuel, which rates broadcast content.
	//
	// Possible values:
	//   "csaUnspecified"
	//   "csaT" - T
	//   "csa10" - 10
	//   "csa12" - 12
	//   "csa16" - 16
	//   "csa18" - 18
	//   "csaInterdiction" - Interdiction
	//   "csaUnrated"
	CsaRating string `json:"csaRating,omitempty"`

	// CscfRating: The video's rating from Luxembourg's Commission de
	// surveillance de la classification des films (CSCF).
	//
	// Possible values:
	//   "cscfUnspecified"
	//   "cscfAl" - AL
	//   "cscfA" - A
	//   "cscf6" - 6
	//   "cscf9" - 9
	//   "cscf12" - 12
	//   "cscf16" - 16
	//   "cscf18" - 18
	//   "cscfUnrated"
	CscfRating string `json:"cscfRating,omitempty"`

	// CzfilmRating: The video's rating in the Czech Republic.
	//
	// Possible values:
	//   "czfilmUnspecified"
	//   "czfilmU" - U
	//   "czfilm12" - 12
	//   "czfilm14" - 14
	//   "czfilm18" - 18
	//   "czfilmUnrated"
	CzfilmRating string `json:"czfilmRating,omitempty"`

	// DjctqRating: The video's Departamento de Justiça, Classificação,
	// Qualificação e Títulos (DJCQT - Brazil) rating.
	//
	// Possible values:
	//   "djctqUnspecified"
	//   "djctqL" - L
	//   "djctq10" - 10
	//   "djctq12" - 12
	//   "djctq14" - 14
	//   "djctq16" - 16
	//   "djctq18" - 18
	//   "djctqEr"
	//   "djctqL10"
	//   "djctqL12"
	//   "djctqL14"
	//   "djctqL16"
	//   "djctqL18"
	//   "djctq1012"
	//   "djctq1014"
	//   "djctq1016"
	//   "djctq1018"
	//   "djctq1214"
	//   "djctq1216"
	//   "djctq1218"
	//   "djctq1416"
	//   "djctq1418"
	//   "djctq1618"
	//   "djctqUnrated"
	DjctqRating string `json:"djctqRating,omitempty"`

	// DjctqRatingReasons: Reasons that explain why the video received its
	// DJCQT (Brazil) rating.
	//
	// Possible values:
	//   "djctqRatingReasonUnspecified"
	//   "djctqViolence" - Brazil rating content descriptors. See
	// http://go/brazilratings section F. Violência (Violence)
	//   "djctqExtremeViolence" - Violência extrema (Extreme violence)
	//   "djctqSexualContent" - Conteúdo sexual (Sexual content)
	//   "djctqNudity" - Nudez (Nudity)
	//   "djctqSex" - Sexo (Sex)
	//   "djctqExplicitSex" - Sexo Explícito (Explicit sex)
	//   "djctqDrugs" - Drogas (Drugs)
	//   "djctqLegalDrugs" - Drogas Lícitas (Legal drugs)
	//   "djctqIllegalDrugs" - Drogas Ilícitas (Illegal drugs)
	//   "djctqInappropriateLanguage" - Linguagem Imprópria (Inappropriate
	// language)
	//   "djctqCriminalActs" - Atos Criminosos (Criminal Acts)
	//   "djctqImpactingContent" - Conteúdo Impactante (Impacting content)
	DjctqRatingReasons []string `json:"djctqRatingReasons,omitempty"`

	// EcbmctRating: Rating system in Turkey - Evaluation and Classification
	// Board of the Ministry of Culture and Tourism
	//
	// Possible values:
	//   "ecbmctUnspecified"
	//   "ecbmctG" - G
	//   "ecbmct7a" - 7A
	//   "ecbmct7plus" - 7+
	//   "ecbmct13a" - 13A
	//   "ecbmct13plus" - 13+
	//   "ecbmct15a" - 15A
	//   "ecbmct15plus" - 15+
	//   "ecbmct18plus" - 18+
	//   "ecbmctUnrated"
	EcbmctRating string `json:"ecbmctRating,omitempty"`

	// EefilmRating: The video's rating in Estonia.
	//
	// Possible values:
	//   "eefilmUnspecified"
	//   "eefilmPere" - Pere
	//   "eefilmL" - L
	//   "eefilmMs6" - MS-6
	//   "eefilmK6" - K-6
	//   "eefilmMs12" - MS-12
	//   "eefilmK12" - K-12
	//   "eefilmK14" - K-14
	//   "eefilmK16" - K-16
	//   "eefilmUnrated"
	EefilmRating string `json:"eefilmRating,omitempty"`

	// EgfilmRating: The video's rating in Egypt.
	//
	// Possible values:
	//   "egfilmUnspecified"
	//   "egfilmGn" - GN
	//   "egfilm18" - 18
	//   "egfilmBn" - BN
	//   "egfilmUnrated"
	EgfilmRating string `json:"egfilmRating,omitempty"`

	// EirinRating: The video's Eirin (映倫) rating. Eirin is the Japanese
	// rating system.
	//
	// Possible values:
	//   "eirinUnspecified"
	//   "eirinG" - G
	//   "eirinPg12" - PG-12
	//   "eirinR15plus" - R15+
	//   "eirinR18plus" - R18+
	//   "eirinUnrated"
	EirinRating string `json:"eirinRating,omitempty"`

	// FcbmRating: The video's rating from Malaysia's Film Censorship Board.
	//
	// Possible values:
	//   "fcbmUnspecified"
	//   "fcbmU" - U
	//   "fcbmPg13" - PG13
	//   "fcbmP13" - P13
	//   "fcbm18" - 18
	//   "fcbm18sx" - 18SX
	//   "fcbm18pa" - 18PA
	//   "fcbm18sg" - 18SG
	//   "fcbm18pl" - 18PL
	//   "fcbmUnrated"
	FcbmRating string `json:"fcbmRating,omitempty"`

	// FcoRating: The video's rating from Hong Kong's Office for Film,
	// Newspaper and Article Administration.
	//
	// Possible values:
	//   "fcoUnspecified"
	//   "fcoI" - I
	//   "fcoIia" - IIA
	//   "fcoIib" - IIB
	//   "fcoIi" - II
	//   "fcoIii" - III
	//   "fcoUnrated"
	FcoRating string `json:"fcoRating,omitempty"`

	// FmocRating: This property has been deprecated. Use the
	// contentDetails.contentRating.cncRating instead.
	//
	// Possible values:
	//   "fmocUnspecified"
	//   "fmocU" - U
	//   "fmoc10" - 10
	//   "fmoc12" - 12
	//   "fmoc16" - 16
	//   "fmoc18" - 18
	//   "fmocE" - E
	//   "fmocUnrated"
	FmocRating string `json:"fmocRating,omitempty"`

	// FpbRating: The video's rating from South Africa's Film and
	// Publication Board.
	//
	// Possible values:
	//   "fpbUnspecified"
	//   "fpbA" - A
	//   "fpbPg" - PG
	//   "fpb79Pg" - 7-9PG
	//   "fpb1012Pg" - 10-12PG
	//   "fpb13" - 13
	//   "fpb16" - 16
	//   "fpb18" - 18
	//   "fpbX18" - X18
	//   "fpbXx" - XX
	//   "fpbUnrated"
	//   "fpb10" - 10
	FpbRating string `json:"fpbRating,omitempty"`

	// FpbRatingReasons: Reasons that explain why the video received its FPB
	// (South Africa) rating.
	//
	// Possible values:
	//   "fpbRatingReasonUnspecified"
	//   "fpbBlasphemy" - South Africa rating content descriptors.
	//   "fpbLanguage"
	//   "fpbNudity"
	//   "fpbPrejudice"
	//   "fpbSex"
	//   "fpbViolence"
	//   "fpbDrugs"
	//   "fpbSexualViolence"
	//   "fpbHorror"
	//   "fpbCriminalTechniques"
	//   "fpbImitativeActsTechniques"
	FpbRatingReasons []string `json:"fpbRatingReasons,omitempty"`

	// FskRating: The video's Freiwillige Selbstkontrolle der Filmwirtschaft
	// (FSK - Germany) rating.
	//
	// Possible values:
	//   "fskUnspecified"
	//   "fsk0" - FSK 0
	//   "fsk6" - FSK 6
	//   "fsk12" - FSK 12
	//   "fsk16" - FSK 16
	//   "fsk18" - FSK 18
	//   "fskUnrated"
	FskRating string `json:"fskRating,omitempty"`

	// GrfilmRating: The video's rating in Greece.
	//
	// Possible values:
	//   "grfilmUnspecified"
	//   "grfilmK" - K
	//   "grfilmE" - E
	//   "grfilmK12" - K-12
	//   "grfilmK13" - K-13
	//   "grfilmK15" - K-15
	//   "grfilmK17" - K-17
	//   "grfilmK18" - K-18
	//   "grfilmUnrated"
	GrfilmRating string `json:"grfilmRating,omitempty"`

	// IcaaRating: The video's Instituto de la Cinematografía y de las
	// Artes Audiovisuales (ICAA - Spain) rating.
	//
	// Possible values:
	//   "icaaUnspecified"
	//   "icaaApta" - APTA
	//   "icaa7" - 7
	//   "icaa12" - 12
	//   "icaa13" - 13
	//   "icaa16" - 16
	//   "icaa18" - 18
	//   "icaaX" - X
	//   "icaaUnrated"
	IcaaRating string `json:"icaaRating,omitempty"`

	// IfcoRating: The video's Irish Film Classification Office (IFCO -
	// Ireland) rating. See the IFCO website for more information.
	//
	// Possible values:
	//   "ifcoUnspecified"
	//   "ifcoG" - G
	//   "ifcoPg" - PG
	//   "ifco12" - 12
	//   "ifco12a" - 12A
	//   "ifco15" - 15
	//   "ifco15a" - 15A
	//   "ifco16" - 16
	//   "ifco18" - 18
	//   "ifcoUnrated"
	IfcoRating string `json:"ifcoRating,omitempty"`

	// IlfilmRating: The video's rating in Israel.
	//
	// Possible values:
	//   "ilfilmUnspecified"
	//   "ilfilmAa" - AA
	//   "ilfilm12" - 12
	//   "ilfilm14" - 14
	//   "ilfilm16" - 16
	//   "ilfilm18" - 18
	//   "ilfilmUnrated"
	IlfilmRating string `json:"ilfilmRating,omitempty"`

	// IncaaRating: The video's INCAA (Instituto Nacional de Cine y Artes
	// Audiovisuales - Argentina) rating.
	//
	// Possible values:
	//   "incaaUnspecified"
	//   "incaaAtp" - ATP (Apta para todo publico)
	//   "incaaSam13" - 13 (Solo apta para mayores de 13 años)
	//   "incaaSam16" - 16 (Solo apta para mayores de 16 años)
	//   "incaaSam18" - 18 (Solo apta para mayores de 18 años)
	//   "incaaC" - X (Solo apta para mayores de 18 años, de exhibición
	// condicionada)
	//   "incaaUnrated"
	IncaaRating string `json:"incaaRating,omitempty"`

	// KfcbRating: The video's rating from the Kenya Film Classification
	// Board.
	//
	// Possible values:
	//   "kfcbUnspecified"
	//   "kfcbG" - GE
	//   "kfcbPg" - PG
	//   "kfcb16plus" - 16
	//   "kfcbR" - 18
	//   "kfcbUnrated"
	KfcbRating string `json:"kfcbRating,omitempty"`

	// KijkwijzerRating: The video's NICAM/Kijkwijzer rating from the
	// Nederlands Instituut voor de Classificatie van Audiovisuele Media
	// (Netherlands).
	//
	// Possible values:
	//   "kijkwijzerUnspecified"
	//   "kijkwijzerAl" - AL
	//   "kijkwijzer6" - 6
	//   "kijkwijzer9" - 9
	//   "kijkwijzer12" - 12
	//   "kijkwijzer16" - 16
	//   "kijkwijzer18"
	//   "kijkwijzerUnrated"
	KijkwijzerRating string `json:"kijkwijzerRating,omitempty"`

	// KmrbRating: The video's Korea Media Rating Board
	// (영상물등급위원회) rating. The KMRB rates videos in South
	// Korea.
	//
	// Possible values:
	//   "kmrbUnspecified"
	//   "kmrbAll" - 전체관람가
	//   "kmrb12plus" - 12세 이상 관람가
	//   "kmrb15plus" - 15세 이상 관람가
	//   "kmrbTeenr"
	//   "kmrbR" - 청소년 관람불가
	//   "kmrbUnrated"
	KmrbRating string `json:"kmrbRating,omitempty"`

	// LsfRating: The video's rating from Indonesia's Lembaga Sensor Film.
	//
	// Possible values:
	//   "lsfUnspecified"
	//   "lsfSu" - SU
	//   "lsfA" - A
	//   "lsfBo" - BO
	//   "lsf13" - 13
	//   "lsfR" - R
	//   "lsf17" - 17
	//   "lsfD" - D
	//   "lsf21" - 21
	//   "lsfUnrated"
	LsfRating string `json:"lsfRating,omitempty"`

	// MccaaRating: The video's rating from Malta's Film Age-Classification
	// Board.
	//
	// Possible values:
	//   "mccaaUnspecified"
	//   "mccaaU" - U
	//   "mccaaPg" - PG
	//   "mccaa12a" - 12A
	//   "mccaa12" - 12
	//   "mccaa14" - 14 - this rating was removed from the new
	// classification structure introduced in 2013.
	//   "mccaa15" - 15
	//   "mccaa16" - 16 - this rating was removed from the new
	// classification structure introduced in 2013.
	//   "mccaa18" - 18
	//   "mccaaUnrated"
	MccaaRating string `json:"mccaaRating,omitempty"`

	// MccypRating: The video's rating from the Danish Film Institute's (Det
	// Danske Filminstitut) Media Council for Children and Young People.
	//
	// Possible values:
	//   "mccypUnspecified"
	//   "mccypA" - A
	//   "mccyp7" - 7
	//   "mccyp11" - 11
	//   "mccyp15" - 15
	//   "mccypUnrated"
	MccypRating string `json:"mccypRating,omitempty"`

	// McstRating: The video's rating system for Vietnam - MCST
	//
	// Possible values:
	//   "mcstUnspecified"
	//   "mcstP" - P
	//   "mcst0" - 0
	//   "mcstC13" - C13
	//   "mcstC16" - C16
	//   "mcst16plus" - 16+
	//   "mcstC18" - C18
	//   "mcstGPg" - MCST_G_PG
	//   "mcstUnrated"
	McstRating string `json:"mcstRating,omitempty"`

	// MdaRating: The video's rating from Singapore's Media Development
	// Authority (MDA) and, specifically, it's Board of Film Censors (BFC).
	//
	// Possible values:
	//   "mdaUnspecified"
	//   "mdaG" - G
	//   "mdaPg" - PG
	//   "mdaPg13" - PG13
	//   "mdaNc16" - NC16
	//   "mdaM18" - M18
	//   "mdaR21" - R21
	//   "mdaUnrated"
	MdaRating string `json:"mdaRating,omitempty"`

	// MedietilsynetRating: The video's rating from Medietilsynet, the
	// Norwegian Media Authority.
	//
	// Possible values:
	//   "medietilsynetUnspecified"
	//   "medietilsynetA" - A
	//   "medietilsynet6" - 6
	//   "medietilsynet7" - 7
	//   "medietilsynet9" - 9
	//   "medietilsynet11" - 11
	//   "medietilsynet12" - 12
	//   "medietilsynet15" - 15
	//   "medietilsynet18" - 18
	//   "medietilsynetUnrated"
	MedietilsynetRating string `json:"medietilsynetRating,omitempty"`

	// MekuRating: The video's rating from Finland's Kansallinen
	// Audiovisuaalinen Instituutti (National Audiovisual Institute).
	//
	// Possible values:
	//   "mekuUnspecified"
	//   "mekuS" - S
	//   "meku7" - 7
	//   "meku12" - 12
	//   "meku16" - 16
	//   "meku18" - 18
	//   "mekuUnrated"
	MekuRating string `json:"mekuRating,omitempty"`

	// MenaMpaaRating: The rating system for MENA countries, a clone of
	// MPAA. It is needed to prevent titles go live w/o additional QC check,
	// since some of them can be inappropriate for the countries at all. See
	// b/33408548 for more details.
	//
	// Possible values:
	//   "menaMpaaUnspecified"
	//   "menaMpaaG" - G
	//   "menaMpaaPg" - PG
	//   "menaMpaaPg13" - PG-13
	//   "menaMpaaR" - R
	//   "menaMpaaUnrated" - To keep the same enum values as MPAA's items
	// have, skip NC_17.
	MenaMpaaRating string `json:"menaMpaaRating,omitempty"`

	// MibacRating: The video's rating from the Ministero dei Beni e delle
	// Attività Culturali e del Turismo (Italy).
	//
	// Possible values:
	//   "mibacUnspecified"
	//   "mibacT"
	//   "mibacVap"
	//   "mibacVm12"
	//   "mibacVm14"
	//   "mibacVm18"
	//   "mibacUnrated"
	MibacRating string `json:"mibacRating,omitempty"`

	// MocRating: The video's Ministerio de Cultura (Colombia) rating.
	//
	// Possible values:
	//   "mocUnspecified"
	//   "mocE" - E
	//   "mocT" - T
	//   "moc7" - 7
	//   "moc12" - 12
	//   "moc15" - 15
	//   "moc18" - 18
	//   "mocX" - X
	//   "mocBanned" - Banned
	//   "mocUnrated"
	MocRating string `json:"mocRating,omitempty"`

	// MoctwRating: The video's rating from Taiwan's Ministry of Culture
	// (文化部).
	//
	// Possible values:
	//   "moctwUnspecified"
	//   "moctwG" - G
	//   "moctwP" - P
	//   "moctwPg" - PG
	//   "moctwR" - R
	//   "moctwUnrated"
	//   "moctwR12" - R-12
	//   "moctwR15" - R-15
	MoctwRating string `json:"moctwRating,omitempty"`

	// MpaaRating: The video's Motion Picture Association of America (MPAA)
	// rating.
	//
	// Possible values:
	//   "mpaaUnspecified"
	//   "mpaaG" - G
	//   "mpaaPg" - PG
	//   "mpaaPg13" - PG-13
	//   "mpaaR" - R
	//   "mpaaNc17" - NC-17
	//   "mpaaX" - ! X
	//   "mpaaUnrated"
	MpaaRating string `json:"mpaaRating,omitempty"`

	// MpaatRating: The rating system for trailer, DVD, and Ad in the US.
	// See http://movielabs.com/md/ratings/v2.3/html/US_MPAAT_Ratings.html.
	//
	// Possible values:
	//   "mpaatUnspecified"
	//   "mpaatGb" - GB
	//   "mpaatRb" - RB
	MpaatRating string `json:"mpaatRating,omitempty"`

	// MtrcbRating: The video's rating from the Movie and Television Review
	// and Classification Board (Philippines).
	//
	// Possible values:
	//   "mtrcbUnspecified"
	//   "mtrcbG" - G
	//   "mtrcbPg" - PG
	//   "mtrcbR13" - R-13
	//   "mtrcbR16" - R-16
	//   "mtrcbR18" - R-18
	//   "mtrcbX" - X
	//   "mtrcbUnrated"
	MtrcbRating string `json:"mtrcbRating,omitempty"`

	// NbcRating: The video's rating from the Maldives National Bureau of
	// Classification.
	//
	// Possible values:
	//   "nbcUnspecified"
	//   "nbcG" - G
	//   "nbcPg" - PG
	//   "nbc12plus" - 12+
	//   "nbc15plus" - 15+
	//   "nbc18plus" - 18+
	//   "nbc18plusr" - 18+R
	//   "nbcPu" - PU
	//   "nbcUnrated"
	NbcRating string `json:"nbcRating,omitempty"`

	// NbcplRating: The video's rating in Poland.
	//
	// Possible values:
	//   "nbcplUnspecified"
	//   "nbcplI"
	//   "nbcplIi"
	//   "nbcplIii"
	//   "nbcplIv"
	//   "nbcpl18plus"
	//   "nbcplUnrated"
	NbcplRating string `json:"nbcplRating,omitempty"`

	// NfrcRating: The video's rating from the Bulgarian National Film
	// Center.
	//
	// Possible values:
	//   "nfrcUnspecified"
	//   "nfrcA" - A
	//   "nfrcB" - B
	//   "nfrcC" - C
	//   "nfrcD" - D
	//   "nfrcX" - X
	//   "nfrcUnrated"
	NfrcRating string `json:"nfrcRating,omitempty"`

	// NfvcbRating: The video's rating from Nigeria's National Film and
	// Video Censors Board.
	//
	// Possible values:
	//   "nfvcbUnspecified"
	//   "nfvcbG" - G
	//   "nfvcbPg" - PG
	//   "nfvcb12" - 12
	//   "nfvcb12a" - 12A
	//   "nfvcb15" - 15
	//   "nfvcb18" - 18
	//   "nfvcbRe" - RE
	//   "nfvcbUnrated"
	NfvcbRating string `json:"nfvcbRating,omitempty"`

	// NkclvRating: The video's rating from the Nacionãlais Kino centrs
	// (National Film Centre of Latvia).
	//
	// Possible values:
	//   "nkclvUnspecified"
	//   "nkclvU" - U
	//   "nkclv7plus" - 7+
	//   "nkclv12plus" - 12+
	//   "nkclv16plus" - ! 16+
	//   "nkclv18plus" - 18+
	//   "nkclvUnrated"
	NkclvRating string `json:"nkclvRating,omitempty"`

	// NmcRating: The National Media Council ratings system for United Arab
	// Emirates.
	//
	// Possible values:
	//   "nmcUnspecified"
	//   "nmcG" - G
	//   "nmcPg" - PG
	//   "nmcPg13" - PG-13
	//   "nmcPg15" - PG-15
	//   "nmc15plus" - 15+
	//   "nmc18plus" - 18+
	//   "nmc18tc" - 18TC
	//   "nmcUnrated"
	NmcRating string `json:"nmcRating,omitempty"`

	// OflcRating: The video's Office of Film and Literature Classification
	// (OFLC - New Zealand) rating.
	//
	// Possible values:
	//   "oflcUnspecified"
	//   "oflcG" - G
	//   "oflcPg" - PG
	//   "oflcM" - M
	//   "oflcR13" - R13
	//   "oflcR15" - R15
	//   "oflcR16" - R16
	//   "oflcR18" - R18
	//   "oflcUnrated"
	//   "oflcRp13" - RP13
	//   "oflcRp16" - RP16
	//   "oflcRp18" - RP18
	OflcRating string `json:"oflcRating,omitempty"`

	// PefilmRating: The video's rating in Peru.
	//
	// Possible values:
	//   "pefilmUnspecified"
	//   "pefilmPt" - PT
	//   "pefilmPg" - PG
	//   "pefilm14" - 14
	//   "pefilm18" - 18
	//   "pefilmUnrated"
	PefilmRating string `json:"pefilmRating,omitempty"`

	// RcnofRating: The video's rating from the Hungarian Nemzeti Filmiroda,
	// the Rating Committee of the National Office of Film.
	//
	// Possible values:
	//   "rcnofUnspecified"
	//   "rcnofI"
	//   "rcnofIi"
	//   "rcnofIii"
	//   "rcnofIv"
	//   "rcnofV"
	//   "rcnofVi"
	//   "rcnofUnrated"
	RcnofRating string `json:"rcnofRating,omitempty"`

	// ResorteviolenciaRating: The video's rating in Venezuela.
	//
	// Possible values:
	//   "resorteviolenciaUnspecified"
	//   "resorteviolenciaA" - A
	//   "resorteviolenciaB" - B
	//   "resorteviolenciaC" - C
	//   "resorteviolenciaD" - D
	//   "resorteviolenciaE" - E
	//   "resorteviolenciaUnrated"
	ResorteviolenciaRating string `json:"resorteviolenciaRating,omitempty"`

	// RtcRating: The video's General Directorate of Radio, Television and
	// Cinematography (Mexico) rating.
	//
	// Possible values:
	//   "rtcUnspecified"
	//   "rtcAa" - AA
	//   "rtcA" - A
	//   "rtcB" - B
	//   "rtcB15" - B15
	//   "rtcC" - C
	//   "rtcD" - D
	//   "rtcUnrated"
	RtcRating string `json:"rtcRating,omitempty"`

	// RteRating: The video's rating from Ireland's Raidió Teilifís
	// Éireann.
	//
	// Possible values:
	//   "rteUnspecified"
	//   "rteGa" - GA
	//   "rteCh" - CH
	//   "rtePs" - PS
	//   "rteMa" - MA
	//   "rteUnrated"
	RteRating string `json:"rteRating,omitempty"`

	// RussiaRating: The video's National Film Registry of the Russian
	// Federation (MKRF - Russia) rating.
	//
	// Possible values:
	//   "russiaUnspecified"
	//   "russia0" - 0+
	//   "russia6" - 6+
	//   "russia12" - 12+
	//   "russia16" - 16+
	//   "russia18" - 18+
	//   "russiaUnrated"
	RussiaRating string `json:"russiaRating,omitempty"`

	// SkfilmRating: The video's rating in Slovakia.
	//
	// Possible values:
	//   "skfilmUnspecified"
	//   "skfilmG" - G
	//   "skfilmP2" - P2
	//   "skfilmP5" - P5
	//   "skfilmP8" - P8
	//   "skfilmUnrated"
	SkfilmRating string `json:"skfilmRating,omitempty"`

	// SmaisRating: The video's rating in Iceland.
	//
	// Possible values:
	//   "smaisUnspecified"
	//   "smaisL" - L
	//   "smais7" - 7
	//   "smais12" - 12
	//   "smais14" - 14
	//   "smais16" - 16
	//   "smais18" - 18
	//   "smaisUnrated"
	SmaisRating string `json:"smaisRating,omitempty"`

	// SmsaRating: The video's rating from Statens medieråd (Sweden's
	// National Media Council).
	//
	// Possible values:
	//   "smsaUnspecified"
	//   "smsaA" - All ages
	//   "smsa7" - 7
	//   "smsa11" - 11
	//   "smsa15" - 15
	//   "smsaUnrated"
	SmsaRating string `json:"smsaRating,omitempty"`

	// TvpgRating: The video's TV Parental Guidelines (TVPG) rating.
	//
	// Possible values:
	//   "tvpgUnspecified"
	//   "tvpgY" - TV-Y
	//   "tvpgY7" - TV-Y7
	//   "tvpgY7Fv" - TV-Y7-FV
	//   "tvpgG" - TV-G
	//   "tvpgPg" - TV-PG
	//   "pg14" - TV-14
	//   "tvpgMa" - TV-MA
	//   "tvpgUnrated"
	TvpgRating string `json:"tvpgRating,omitempty"`

	// YtRating: A rating that YouTube uses to identify age-restricted
	// content.
	//
	// Possible values:
	//   "ytUnspecified"
	//   "ytAgeRestricted"
	YtRating string `json:"ytRating,omitempty"`

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

type Entity struct {
	Id string `json:"id,omitempty"`

	TypeId string `json:"typeId,omitempty"`

	Url string `json:"url,omitempty"`

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

// GeoPoint: Geographical coordinates of a point, in WGS84.
type GeoPoint struct {
	// Altitude: Altitude above the reference ellipsoid, in meters.
	Altitude float64 `json:"altitude,omitempty"`

	// Latitude: Latitude in degrees.
	Latitude float64 `json:"latitude,omitempty"`

	// Longitude: Longitude in degrees.
	Longitude float64 `json:"longitude,omitempty"`

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

func (s *GeoPoint) UnmarshalJSON(data []byte) error {
	type NoMethod GeoPoint
	var s1 struct {
		Altitude  gensupport.JSONFloat64 `json:"altitude"`
		Latitude  gensupport.JSONFloat64 `json:"latitude"`
		Longitude gensupport.JSONFloat64 `json:"longitude"`
		*NoMethod
	}
	s1.NoMethod = (*NoMethod)(s)
	if err := json.Unmarshal(data, &s1); err != nil {
		return err
	}
	s.Altitude = float64(s1.Altitude)
	s.Latitude = float64(s1.Latitude)
	s.Longitude = float64(s1.Longitude)
	return nil
}

// I18nLanguage: An *i18nLanguage* resource identifies a UI language
// currently supported by YouTube.
type I18nLanguage struct {
	// Etag: Etag of this resource.
	Etag string `json:"etag,omitempty"`

	// Id: The ID that YouTube uses to uniquely identify the i18n language.
	Id string `json:"id,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "youtube#i18nLanguage".
	Kind string `json:"kind,omitempty"`

	// Snippet: The snippet object contains basic details about the i18n
	// language, such as language code and human-readable name.
	Snippet *I18nLanguageSnippet `json:"snippet,omitempty"`

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

type I18nLanguageListResponse struct {
	// Etag: Etag of this resource.
	Etag string `json:"etag,omitempty"`

	// EventId: Serialized EventId of the request which produced this
	// response.
	EventId string `json:"eventId,omitempty"`

	// Items: A list of supported i18n languages. In this map, the i18n
	// language ID is the map key, and its value is the corresponding
	// i18nLanguage resource.
	Items []*I18nLanguage `json:"items,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "youtube#i18nLanguageListResponse".
	Kind string `json:"kind,omitempty"`

	// VisitorId: The visitorId identifies the visitor.
	VisitorId string `json:"visitorId,omitempty"`

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

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

// I18nLanguageSnippet: Basic details about an i18n language, such as
// language code and human-readable name.
type I18nLanguageSnippet struct {
	// Hl: A short BCP-47 code that uniquely identifies a language.
	Hl string `json:"hl,omitempty"`

	// Name: The human-readable name of the language in the language itself.
	Name string `json:"name,omitempty"`

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

// I18nRegion: A *i18nRegion* resource identifies a region where YouTube
// is available.
type I18nRegion struct {
	// Etag: Etag of this resource.
	Etag string `json:"etag,omitempty"`

	// Id: The ID that YouTube uses to uniquely identify the i18n region.
	Id string `json:"id,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "youtube#i18nRegion".
	Kind string `json:"kind,omitempty"`

	// Snippet: The snippet object contains basic details about the i18n
	// region, such as region code and human-readable name.
	Snippet *I18nRegionSnippet `json:"snippet,omitempty"`

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

type I18nRegionListResponse struct {
	// Etag: Etag of this resource.
	Etag string `json:"etag,omitempty"`

	// EventId: Serialized EventId of the request which produced this
	// response.
	EventId string `json:"eventId,omitempty"`

	// Items: A list of regions where YouTube is available. In this map, the
	// i18n region ID is the map key, and its value is the corresponding
	// i18nRegion resource.
	Items []*I18nRegion `json:"items,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "youtube#i18nRegionListResponse".
	Kind string `json:"kind,omitempty"`

	// VisitorId: The visitorId identifies the visitor.
	VisitorId string `json:"visitorId,omitempty"`

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

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

// I18nRegionSnippet: Basic details about an i18n region, such as region
// code and human-readable name.
type I18nRegionSnippet struct {
	// Gl: The region code as a 2-letter ISO country code.
	Gl string `json:"gl,omitempty"`

	// Name: The human-readable name of the region.
	Name string `json:"name,omitempty"`

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

// ImageSettings: Branding properties for images associated with the
// channel.
type ImageSettings struct {
	// BackgroundImageUrl: The URL for the background image shown on the
	// video watch page. The image should be 1200px by 615px, with a maximum
	// file size of 128k.
	BackgroundImageUrl *LocalizedProperty `json:"backgroundImageUrl,omitempty"`

	// BannerExternalUrl: This is used only in update requests; if it's set,
	// we use this URL to generate all of the above banner URLs.
	BannerExternalUrl string `json:"bannerExternalUrl,omitempty"`

	// BannerImageUrl: Banner image. Desktop size (1060x175).
	BannerImageUrl string `json:"bannerImageUrl,omitempty"`

	// BannerMobileExtraHdImageUrl: Banner image. Mobile size high
	// resolution (1440x395).
	BannerMobileExtraHdImageUrl string `json:"bannerMobileExtraHdImageUrl,omitempty"`

	// BannerMobileHdImageUrl: Banner image. Mobile size high resolution
	// (1280x360).
	BannerMobileHdImageUrl string `json:"bannerMobileHdImageUrl,omitempty"`

	// BannerMobileImageUrl: Banner image. Mobile size (640x175).
	BannerMobileImageUrl string `json:"bannerMobileImageUrl,omitempty"`

	// BannerMobileLowImageUrl: Banner image. Mobile size low resolution
	// (320x88).
	BannerMobileLowImageUrl string `json:"bannerMobileLowImageUrl,omitempty"`

	// BannerMobileMediumHdImageUrl: Banner image. Mobile size medium/high
	// resolution (960x263).
	BannerMobileMediumHdImageUrl string `json:"bannerMobileMediumHdImageUrl,omitempty"`

	// BannerTabletExtraHdImageUrl: Banner image. Tablet size extra high
	// resolution (2560x424).
	BannerTabletExtraHdImageUrl string `json:"bannerTabletExtraHdImageUrl,omitempty"`

	// BannerTabletHdImageUrl: Banner image. Tablet size high resolution
	// (2276x377).
	BannerTabletHdImageUrl string `json:"bannerTabletHdImageUrl,omitempty"`

	// BannerTabletImageUrl: Banner image. Tablet size (1707x283).
	BannerTabletImageUrl string `json:"bannerTabletImageUrl,omitempty"`

	// BannerTabletLowImageUrl: Banner image. Tablet size low resolution
	// (1138x188).
	BannerTabletLowImageUrl string `json:"bannerTabletLowImageUrl,omitempty"`

	// BannerTvHighImageUrl: Banner image. TV size high resolution
	// (1920x1080).
	BannerTvHighImageUrl string `json:"bannerTvHighImageUrl,omitempty"`

	// BannerTvImageUrl: Banner image. TV size extra high resolution
	// (2120x1192).
	BannerTvImageUrl string `json:"bannerTvImageUrl,omitempty"`

	// BannerTvLowImageUrl: Banner image. TV size low resolution (854x480).
	BannerTvLowImageUrl string `json:"bannerTvLowImageUrl,omitempty"`

	// BannerTvMediumImageUrl: Banner image. TV size medium resolution
	// (1280x720).
	BannerTvMediumImageUrl string `json:"bannerTvMediumImageUrl,omitempty"`

	// LargeBrandedBannerImageImapScript: The image map script for the large
	// banner image.
	LargeBrandedBannerImageImapScript *LocalizedProperty `json:"largeBrandedBannerImageImapScript,omitempty"`

	// LargeBrandedBannerImageUrl: The URL for the 854px by 70px image that
	// appears below the video player in the expanded video view of the
	// video watch page.
	LargeBrandedBannerImageUrl *LocalizedProperty `json:"largeBrandedBannerImageUrl,omitempty"`

	// SmallBrandedBannerImageImapScript: The image map script for the small
	// banner image.
	SmallBrandedBannerImageImapScript *LocalizedProperty `json:"smallBrandedBannerImageImapScript,omitempty"`

	// SmallBrandedBannerImageUrl: The URL for the 640px by 70px banner
	// image that appears below the video player in the default view of the
	// video watch page. The URL for the image that appears above the
	// top-left corner of the video player. This is a 25-pixel-high image
	// with a flexible width that cannot exceed 170 pixels.
	SmallBrandedBannerImageUrl *LocalizedProperty `json:"smallBrandedBannerImageUrl,omitempty"`

	// TrackingImageUrl: The URL for a 1px by 1px tracking pixel that can be
	// used to collect statistics for views of the channel or video pages.
	TrackingImageUrl string `json:"trackingImageUrl,omitempty"`

	WatchIconImageUrl string `json:"watchIconImageUrl,omitempty"`

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

// IngestionInfo: Describes information necessary for ingesting an RTMP
// or an HTTP stream.
type IngestionInfo struct {
	// BackupIngestionAddress: The backup ingestion URL that you should use
	// to stream video to YouTube. You have the option of simultaneously
	// streaming the content that you are sending to the ingestionAddress to
	// this URL.
	BackupIngestionAddress string `json:"backupIngestionAddress,omitempty"`

	// IngestionAddress: The primary ingestion URL that you should use to
	// stream video to YouTube. You must stream video to this URL. Depending
	// on which application or tool you use to encode your video stream, you
	// may need to enter the stream URL and stream name separately or you
	// may need to concatenate them in the following format:
	// *STREAM_URL/STREAM_NAME*
	IngestionAddress string `json:"ingestionAddress,omitempty"`

	// RtmpsBackupIngestionAddress: This ingestion url may be used instead
	// of backupIngestionAddress in order to stream via RTMPS. Not
	// applicable to non-RTMP streams.
	RtmpsBackupIngestionAddress string `json:"rtmpsBackupIngestionAddress,omitempty"`

	// RtmpsIngestionAddress: This ingestion url may be used instead of
	// ingestionAddress in order to stream via RTMPS. Not applicable to
	// non-RTMP streams.
	RtmpsIngestionAddress string `json:"rtmpsIngestionAddress,omitempty"`

	// StreamName: The HTTP or RTMP stream name that YouTube assigns to the
	// video stream.
	StreamName string `json:"streamName,omitempty"`

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

// InvideoBranding: LINT.IfChange Describes an invideo branding.
type InvideoBranding struct {
	// ImageBytes: The bytes the uploaded image. Only used in api to youtube
	// communication.
	ImageBytes string `json:"imageBytes,omitempty"`

	// ImageUrl: The url of the uploaded image. Only used in apiary to api
	// communication.
	ImageUrl string `json:"imageUrl,omitempty"`

	// Position: The spatial position within the video where the branding
	// watermark will be displayed.
	Position *InvideoPosition `json:"position,omitempty"`

	// TargetChannelId: The channel to which this branding links. If not
	// present it defaults to the current channel.
	TargetChannelId string `json:"targetChannelId,omitempty"`

	// Timing: The temporal position within the video where watermark will
	// be displayed.
	Timing *InvideoTiming `json:"timing,omitempty"`

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

// InvideoPosition: Describes the spatial position of a visual widget
// inside a video. It is a union of various position types, out of which
// only will be set one.
type InvideoPosition struct {
	// CornerPosition: Describes in which corner of the video the visual
	// widget will appear.
	//
	// Possible values:
	//   "topLeft"
	//   "topRight"
	//   "bottomLeft"
	//   "bottomRight"
	CornerPosition string `json:"cornerPosition,omitempty"`

	// Type: Defines the position type.
	//
	// Possible values:
	//   "corner"
	Type string `json:"type,omitempty"`

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

// InvideoPromotion: Describes an invideo promotion campaign consisting
// of multiple promoted items. A campaign belongs to a single
// channel_id.
type InvideoPromotion struct {
	// DefaultTiming: The default temporal position within the video where
	// the promoted item will be displayed. Can be overridden by more
	// specific timing in the item.
	DefaultTiming *InvideoTiming `json:"defaultTiming,omitempty"`

	// Items: List of promoted items in decreasing priority.
	Items []*PromotedItem `json:"items,omitempty"`

	// Position: The spatial position within the video where the promoted
	// item will be displayed.
	Position *InvideoPosition `json:"position,omitempty"`

	// UseSmartTiming: Indicates whether the channel's promotional campaign
	// uses "smart timing." This feature attempts to show promotions at a
	// point in the video when they are more likely to be clicked and less
	// likely to disrupt the viewing experience. This feature also picks up
	// a single promotion to show on each video.
	UseSmartTiming bool `json:"useSmartTiming,omitempty"`

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

// InvideoTiming: Describes a temporal position of a visual widget
// inside a video.
type InvideoTiming struct {
	// DurationMs: Defines the duration in milliseconds for which the
	// promotion should be displayed. If missing, the client should use the
	// default.
	DurationMs uint64 `json:"durationMs,omitempty,string"`

	// OffsetMs: Defines the time at which the promotion will appear.
	// Depending on the value of type the value of the offsetMs field will
	// represent a time offset from the start or from the end of the video,
	// expressed in milliseconds.
	OffsetMs uint64 `json:"offsetMs,omitempty,string"`

	// Type: Describes a timing type. If the value is offsetFromStart, then
	// the offsetMs field represents an offset from the start of the video.
	// If the value is offsetFromEnd, then the offsetMs field represents an
	// offset from the end of the video.
	//
	// Possible values:
	//   "offsetFromStart"
	//   "offsetFromEnd"
	Type string `json:"type,omitempty"`

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

type LanguageTag struct {
	Value string `json:"value,omitempty"`

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

type LevelDetails struct {
	// DisplayName: The name that should be used when referring to this
	// level.
	DisplayName string `json:"displayName,omitempty"`

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

// LiveBroadcast: A *liveBroadcast* resource represents an event that
// will be streamed, via live video, on YouTube.
type LiveBroadcast struct {
	// ContentDetails: The contentDetails object contains information about
	// the event's video content, such as whether the content can be shown
	// in an embedded video player or if it will be archived and therefore
	// available for viewing after the event has concluded.
	ContentDetails *LiveBroadcastContentDetails `json:"contentDetails,omitempty"`

	// Etag: Etag of this resource.
	Etag string `json:"etag,omitempty"`

	// Id: The ID that YouTube assigns to uniquely identify the broadcast.
	Id string `json:"id,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "youtube#liveBroadcast".
	Kind string `json:"kind,omitempty"`

	// Snippet: The snippet object contains basic details about the event,
	// including its title, description, start time, and end time.
	Snippet *LiveBroadcastSnippet `json:"snippet,omitempty"`

	// Statistics: The statistics object contains info about the event's
	// current stats. These include concurrent viewers and total chat count.
	// Statistics can change (in either direction) during the lifetime of an
	// event. Statistics are only returned while the event is live.
	Statistics *LiveBroadcastStatistics `json:"statistics,omitempty"`

	// Status: The status object contains information about the event's
	// status.
	Status *LiveBroadcastStatus `json:"status,omitempty"`

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

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

// LiveBroadcastContentDetails: Detailed settings of a broadcast.
type LiveBroadcastContentDetails struct {
	// BoundStreamId: This value uniquely identifies the live stream bound
	// to the broadcast.
	BoundStreamId string `json:"boundStreamId,omitempty"`

	// BoundStreamLastUpdateTimeMs: The date and time that the live stream
	// referenced by boundStreamId was last updated.
	BoundStreamLastUpdateTimeMs string `json:"boundStreamLastUpdateTimeMs,omitempty"`

	// Possible values:
	//   "closedCaptionsTypeUnspecified"
	//   "closedCaptionsDisabled"
	//   "closedCaptionsHttpPost"
	//   "closedCaptionsEmbedded"
	ClosedCaptionsType string `json:"closedCaptionsType,omitempty"`

	// EnableAutoStart: This setting indicates whether auto start is enabled
	// for this broadcast. The default value for this property is false.
	// This setting can only be used by Events.
	EnableAutoStart bool `json:"enableAutoStart,omitempty"`

	// EnableAutoStop: This setting indicates whether auto stop is enabled
	// for this broadcast. The default value for this property is false.
	// This setting can only be used by Events.
	EnableAutoStop bool `json:"enableAutoStop,omitempty"`

	// EnableClosedCaptions: This setting indicates whether HTTP POST closed
	// captioning is enabled for this broadcast. The ingestion URL of the
	// closed captions is returned through the liveStreams API. This is
	// mutually exclusive with using the closed_captions_type property, and
	// is equivalent to setting closed_captions_type to
	// CLOSED_CAPTIONS_HTTP_POST.
	EnableClosedCaptions bool `json:"enableClosedCaptions,omitempty"`

	// EnableContentEncryption: This setting indicates whether YouTube
	// should enable content encryption for the broadcast.
	EnableContentEncryption bool `json:"enableContentEncryption,omitempty"`

	// EnableDvr: This setting determines whether viewers can access DVR
	// controls while watching the video. DVR controls enable the viewer to
	// control the video playback experience by pausing, rewinding, or fast
	// forwarding content. The default value for this property is true.
	// *Important:* You must set the value to true and also set the
	// enableArchive property's value to true if you want to make playback
	// available immediately after the broadcast ends.
	EnableDvr bool `json:"enableDvr,omitempty"`

	// EnableEmbed: This setting indicates whether the broadcast video can
	// be played in an embedded player. If you choose to archive the video
	// (using the enableArchive property), this setting will also apply to
	// the archived video.
	EnableEmbed bool `json:"enableEmbed,omitempty"`

	// EnableLowLatency: Indicates whether this broadcast has low latency
	// enabled.
	EnableLowLatency bool `json:"enableLowLatency,omitempty"`

	// LatencyPreference: If both this and enable_low_latency are set, they
	// must match. LATENCY_NORMAL should match enable_low_latency=false
	// LATENCY_LOW should match enable_low_latency=true LATENCY_ULTRA_LOW
	// should have enable_low_latency omitted.
	//
	// Possible values:
	//   "latencyPreferenceUnspecified"
	//   "normal" - Best for: highest quality viewer playbacks and higher
	// resolutions.
	//   "low" - Best for: near real-time interaction, with minimal playback
	// buffering.
	//   "ultraLow" - Best for: real-time interaction Does not support:
	// Closed captions, 1440p, and 4k resolutions
	LatencyPreference string `json:"latencyPreference,omitempty"`

	// Mesh: The mesh for projecting the video if projection is mesh. The
	// mesh value must be a UTF-8 string containing the base-64 encoding of
	// 3D mesh data that follows the Spherical Video V2 RFC specification
	// for an mshp box, excluding the box size and type but including the
	// following four reserved zero bytes for the version and flags.
	Mesh string `json:"mesh,omitempty"`

	// MonitorStream: The monitorStream object contains information about
	// the monitor stream, which the broadcaster can use to review the event
	// content before the broadcast stream is shown publicly.
	MonitorStream *MonitorStreamInfo `json:"monitorStream,omitempty"`

	// Projection: The projection format of this broadcast. This defaults to
	// rectangular.
	//
	// Possible values:
	//   "projectionUnspecified"
	//   "rectangular"
	//   "360"
	//   "mesh"
	Projection string `json:"projection,omitempty"`

	// RecordFromStart: Automatically start recording after the event goes
	// live. The default value for this property is true. *Important:* You
	// must also set the enableDvr property's value to true if you want the
	// playback to be available immediately after the broadcast ends. If you
	// set this property's value to true but do not also set the enableDvr
	// property to true, there may be a delay of around one day before the
	// archived video will be available for playback.
	RecordFromStart bool `json:"recordFromStart,omitempty"`

	// StartWithSlate: This setting indicates whether the broadcast should
	// automatically begin with an in-stream slate when you update the
	// broadcast's status to live. After updating the status, you then need
	// to send a liveCuepoints.insert request that sets the cuepoint's
	// eventState to end to remove the in-stream slate and make your
	// broadcast stream visible to viewers.
	StartWithSlate bool `json:"startWithSlate,omitempty"`

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

type LiveBroadcastListResponse struct {
	// Etag: Etag of this resource.
	Etag string `json:"etag,omitempty"`

	// EventId: Serialized EventId of the request which produced this
	// response.
	EventId string `json:"eventId,omitempty"`

	// Items: A list of broadcasts that match the request criteria.
	Items []*LiveBroadcast `json:"items,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "youtube#liveBroadcastListResponse".
	Kind string `json:"kind,omitempty"`

	// NextPageToken: The token that can be used as the value of the
	// pageToken parameter to retrieve the next page in the result set.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// PageInfo: General pagination information.
	PageInfo *PageInfo `json:"pageInfo,omitempty"`

	// PrevPageToken: The token that can be used as the value of the
	// pageToken parameter to retrieve the previous page in the result set.
	PrevPageToken string `json:"prevPageToken,omitempty"`

	TokenPagination *TokenPagination `json:"tokenPagination,omitempty"`

	// VisitorId: The visitorId identifies the visitor.
	VisitorId string `json:"visitorId,omitempty"`

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

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

// LiveBroadcastSnippet: Basic broadcast information.
type LiveBroadcastSnippet struct {
	// ActualEndTime: The date and time that the broadcast actually ended.
	// This information is only available once the broadcast's state is
	// complete. The value is specified in ISO 8601 format.
	ActualEndTime string `json:"actualEndTime,omitempty"`

	// ActualStartTime: The date and time that the broadcast actually
	// started. This information is only available once the broadcast's
	// state is live. The value is specified in ISO 8601 format.
	ActualStartTime string `json:"actualStartTime,omitempty"`

	// ChannelId: The ID that YouTube uses to uniquely identify the channel
	// that is publishing the broadcast.
	ChannelId string `json:"channelId,omitempty"`

	// Description: The broadcast's description. As with the title, you can
	// set this field by modifying the broadcast resource or by setting the
	// description field of the corresponding video resource.
	Description string `json:"description,omitempty"`

	// IsDefaultBroadcast: Indicates whether this broadcast is the default
	// broadcast. Internal only.
	IsDefaultBroadcast bool `json:"isDefaultBroadcast,omitempty"`

	// LiveChatId: The id of the live chat for this broadcast.
	LiveChatId string `json:"liveChatId,omitempty"`

	// PublishedAt: The date and time that the broadcast was added to
	// YouTube's live broadcast schedule. The value is specified in ISO 8601
	// format.
	PublishedAt string `json:"publishedAt,omitempty"`

	// ScheduledEndTime: The date and time that the broadcast is scheduled
	// to end. The value is specified in ISO 8601 format.
	ScheduledEndTime string `json:"scheduledEndTime,omitempty"`

	// ScheduledStartTime: The date and time that the broadcast is scheduled
	// to start. The value is specified in ISO 8601 format.
	ScheduledStartTime string `json:"scheduledStartTime,omitempty"`

	// Thumbnails: A map of thumbnail images associated with the broadcast.
	// For each nested object in this object, the key is the name of the
	// thumbnail image, and the value is an object that contains other
	// information about the thumbnail.
	Thumbnails *ThumbnailDetails `json:"thumbnails,omitempty"`

	// Title: The broadcast's title. Note that the broadcast represents
	// exactly one YouTube video. You can set this field by modifying the
	// broadcast resource or by setting the title field of the corresponding
	// video resource.
	Title string `json:"title,omitempty"`

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

// LiveBroadcastStatistics: Statistics about the live broadcast. These
// represent a snapshot of the values at the time of the request.
// Statistics are only returned for live broadcasts.
type LiveBroadcastStatistics struct {
	// TotalChatCount: The total number of live chat messages currently on
	// the broadcast. The property and its value will be present if the
	// broadcast is public, has the live chat feature enabled, and has at
	// least one message. Note that this field will not be filled after the
	// broadcast ends. So this property would not identify the number of
	// chat messages for an archived video of a completed live broadcast.
	TotalChatCount uint64 `json:"totalChatCount,omitempty,string"`

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

// LiveBroadcastStatus: Live broadcast state.
type LiveBroadcastStatus struct {
	// LifeCycleStatus: The broadcast's status. The status can be updated
	// using the API's liveBroadcasts.transition method.
	//
	// Possible values:
	//   "lifeCycleStatusUnspecified" - No value or the value is unknown.
	//   "created" - Incomplete settings, but otherwise valid
	//   "ready" - Complete settings
	//   "testing" - Visible only to partner, may need special UI treatment
	//   "live" - Viper is recording; this means the "clock" is running
	//   "complete" - The broadcast is finished.
	//   "revoked" - This broadcast was removed by admin action
	//   "testStarting" - Transition into TESTING has been requested
	//   "liveStarting" - Transition into LIVE has been requested
	LifeCycleStatus string `json:"lifeCycleStatus,omitempty"`

	// LiveBroadcastPriority: Priority of the live broadcast event (internal
	// state).
	//
	// Possible values:
	//   "liveBroadcastPriorityUnspecified"
	//   "low" - Low priority broadcast: for low view count HoAs or other
	// low priority broadcasts.
	//   "normal" - Normal priority broadcast: for regular HoAs and
	// broadcasts.
	//   "high" - High priority broadcast: for high profile HoAs, like
	// PixelCorp ones.
	LiveBroadcastPriority string `json:"liveBroadcastPriority,omitempty"`

	// MadeForKids: Whether the broadcast is made for kids or not, decided
	// by YouTube instead of the creator. This field is read only.
	MadeForKids bool `json:"madeForKids,omitempty"`

	// PrivacyStatus: The broadcast's privacy status. Note that the
	// broadcast represents exactly one YouTube video, so the privacy
	// settings are identical to those supported for videos. In addition,
	// you can set this field by modifying the broadcast resource or by
	// setting the privacyStatus field of the corresponding video resource.
	//
	// Possible values:
	//   "public"
	//   "unlisted"
	//   "private"
	PrivacyStatus string `json:"privacyStatus,omitempty"`

	// RecordingStatus: The broadcast's recording status.
	//
	// Possible values:
	//   "liveBroadcastRecordingStatusUnspecified" - No value or the value
	// is unknown.
	//   "notRecording" - The recording has not yet been started.
	//   "recording" - The recording is currently on.
	//   "recorded" - The recording is completed, and cannot be started
	// again.
	RecordingStatus string `json:"recordingStatus,omitempty"`

	// SelfDeclaredMadeForKids: This field will be set to True if the
	// creator declares the broadcast to be kids only: go/live-cw-work.
	SelfDeclaredMadeForKids bool `json:"selfDeclaredMadeForKids,omitempty"`

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

// LiveChatBan: A `__liveChatBan__` resource represents a ban for a
// YouTube live chat.
type LiveChatBan struct {
	// Etag: Etag of this resource.
	Etag string `json:"etag,omitempty"`

	// Id: The ID that YouTube assigns to uniquely identify the ban.
	Id string `json:"id,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "youtube#liveChatBan".
	Kind string `json:"kind,omitempty"`

	// Snippet: The `snippet` object contains basic details about the ban.
	Snippet *LiveChatBanSnippet `json:"snippet,omitempty"`

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

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

type LiveChatBanSnippet struct {
	// BanDurationSeconds: The duration of a ban, only filled if the ban has
	// type TEMPORARY.
	BanDurationSeconds uint64 `json:"banDurationSeconds,omitempty,string"`

	BannedUserDetails *ChannelProfileDetails `json:"bannedUserDetails,omitempty"`

	// LiveChatId: The chat this ban is pertinent to.
	LiveChatId string `json:"liveChatId,omitempty"`

	// Type: The type of ban.
	//
	// Possible values:
	//   "liveChatBanTypeUnspecified" - An invalid ban type.
	//   "permanent" - A permanent ban.
	//   "temporary" - A temporary ban.
	Type string `json:"type,omitempty"`

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

type LiveChatFanFundingEventDetails struct {
	// AmountDisplayString: A rendered string that displays the fund amount
	// and currency to the user.
	AmountDisplayString string `json:"amountDisplayString,omitempty"`

	// AmountMicros: The amount of the fund.
	AmountMicros uint64 `json:"amountMicros,omitempty,string"`

	// Currency: The currency in which the fund was made.
	Currency string `json:"currency,omitempty"`

	// UserComment: The comment added by the user to this fan funding event.
	UserComment string `json:"userComment,omitempty"`

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

// LiveChatMessage: A *liveChatMessage* resource represents a chat
// message in a YouTube Live Chat.
type LiveChatMessage struct {
	// AuthorDetails: The authorDetails object contains basic details about
	// the user that posted this message.
	AuthorDetails *LiveChatMessageAuthorDetails `json:"authorDetails,omitempty"`

	// Etag: Etag of this resource.
	Etag string `json:"etag,omitempty"`

	// Id: The ID that YouTube assigns to uniquely identify the message.
	Id string `json:"id,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "youtube#liveChatMessage".
	Kind string `json:"kind,omitempty"`

	// Snippet: The snippet object contains basic details about the message.
	Snippet *LiveChatMessageSnippet `json:"snippet,omitempty"`

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

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

type LiveChatMessageAuthorDetails struct {
	// ChannelId: The YouTube channel ID.
	ChannelId string `json:"channelId,omitempty"`

	// ChannelUrl: The channel's URL.
	ChannelUrl string `json:"channelUrl,omitempty"`

	// DisplayName: The channel's display name.
	DisplayName string `json:"displayName,omitempty"`

	// IsChatModerator: Whether the author is a moderator of the live chat.
	IsChatModerator bool `json:"isChatModerator,omitempty"`

	// IsChatOwner: Whether the author is the owner of the live chat.
	IsChatOwner bool `json:"isChatOwner,omitempty"`

	// IsChatSponsor: Whether the author is a sponsor of the live chat.
	IsChatSponsor bool `json:"isChatSponsor,omitempty"`

	// IsVerified: Whether the author's identity has been verified by
	// YouTube.
	IsVerified bool `json:"isVerified,omitempty"`

	// ProfileImageUrl: The channels's avatar URL.
	ProfileImageUrl string `json:"profileImageUrl,omitempty"`

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

type LiveChatMessageDeletedDetails struct {
	DeletedMessageId string `json:"deletedMessageId,omitempty"`

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

type LiveChatMessageListResponse struct {
	// Etag: Etag of this resource.
	Etag string `json:"etag,omitempty"`

	// EventId: Serialized EventId of the request which produced this
	// response.
	EventId string `json:"eventId,omitempty"`

	Items []*LiveChatMessage `json:"items,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "youtube#liveChatMessageListResponse".
	Kind string `json:"kind,omitempty"`

	NextPageToken string `json:"nextPageToken,omitempty"`

	// OfflineAt: The date and time when the underlying stream went offline.
	// The value is specified in ISO 8601 format.
	OfflineAt string `json:"offlineAt,omitempty"`

	// PageInfo: General pagination information.
	PageInfo *PageInfo `json:"pageInfo,omitempty"`

	// PollingIntervalMillis: The amount of time the client should wait
	// before polling again.
	PollingIntervalMillis int64 `json:"pollingIntervalMillis,omitempty"`

	TokenPagination *TokenPagination `json:"tokenPagination,omitempty"`

	// VisitorId: The visitorId identifies the visitor.
	VisitorId string `json:"visitorId,omitempty"`

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

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

type LiveChatMessageRetractedDetails struct {
	RetractedMessageId string `json:"retractedMessageId,omitempty"`

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

type LiveChatMessageSnippet struct {
	// AuthorChannelId: The ID of the user that authored this message, this
	// field is not always filled. textMessageEvent - the user that wrote
	// the message fanFundingEvent - the user that funded the broadcast
	// newSponsorEvent - the user that just became a sponsor
	// messageDeletedEvent - the moderator that took the action
	// messageRetractedEvent - the author that retracted their message
	// userBannedEvent - the moderator that took the action superChatEvent -
	// the user that made the purchase
	AuthorChannelId string `json:"authorChannelId,omitempty"`

	// DisplayMessage: Contains a string that can be displayed to the user.
	// If this field is not present the message is silent, at the moment
	// only messages of type TOMBSTONE and CHAT_ENDED_EVENT are silent.
	DisplayMessage string `json:"displayMessage,omitempty"`

	// FanFundingEventDetails: Details about the funding event, this is only
	// set if the type is 'fanFundingEvent'.
	FanFundingEventDetails *LiveChatFanFundingEventDetails `json:"fanFundingEventDetails,omitempty"`

	// HasDisplayContent: Whether the message has display content that
	// should be displayed to users.
	HasDisplayContent bool `json:"hasDisplayContent,omitempty"`

	LiveChatId string `json:"liveChatId,omitempty"`

	MessageDeletedDetails *LiveChatMessageDeletedDetails `json:"messageDeletedDetails,omitempty"`

	MessageRetractedDetails *LiveChatMessageRetractedDetails `json:"messageRetractedDetails,omitempty"`

	// PublishedAt: The date and time when the message was orignally
	// published. The value is specified in ISO 8601 format.
	PublishedAt string `json:"publishedAt,omitempty"`

	// SuperChatDetails: Details about the Super Chat event, this is only
	// set if the type is 'superChatEvent'.
	SuperChatDetails *LiveChatSuperChatDetails `json:"superChatDetails,omitempty"`

	// SuperStickerDetails: Details about the Super Sticker event, this is
	// only set if the type is 'superStickerEvent'.
	SuperStickerDetails *LiveChatSuperStickerDetails `json:"superStickerDetails,omitempty"`

	// TextMessageDetails: Details about the text message, this is only set
	// if the type is 'textMessageEvent'.
	TextMessageDetails *LiveChatTextMessageDetails `json:"textMessageDetails,omitempty"`

	// Type: The type of message, this will always be present, it determines
	// the contents of the message as well as which fields will be present.
	//
	// Possible values:
	//   "invalidType"
	//   "textMessageEvent"
	//   "tombstone"
	//   "fanFundingEvent"
	//   "chatEndedEvent"
	//   "sponsorOnlyModeStartedEvent"
	//   "sponsorOnlyModeEndedEvent"
	//   "newSponsorEvent"
	//   "messageDeletedEvent"
	//   "messageRetractedEvent"
	//   "userBannedEvent"
	//   "superChatEvent"
	//   "superStickerEvent"
	Type string `json:"type,omitempty"`

	UserBannedDetails *LiveChatUserBannedMessageDetails `json:"userBannedDetails,omitempty"`

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

// LiveChatModerator: A *liveChatModerator* resource represents a
// moderator for a YouTube live chat. A chat moderator has the ability
// to ban/unban users from a chat, remove message, etc.
type LiveChatModerator struct {
	// Etag: Etag of this resource.
	Etag string `json:"etag,omitempty"`

	// Id: The ID that YouTube assigns to uniquely identify the moderator.
	Id string `json:"id,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "youtube#liveChatModerator".
	Kind string `json:"kind,omitempty"`

	// Snippet: The snippet object contains basic details about the
	// moderator.
	Snippet *LiveChatModeratorSnippet `json:"snippet,omitempty"`

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

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

type LiveChatModeratorListResponse struct {
	// Etag: Etag of this resource.
	Etag string `json:"etag,omitempty"`

	// EventId: Serialized EventId of the request which produced this
	// response.
	EventId string `json:"eventId,omitempty"`

	// Items: A list of moderators that match the request criteria.
	Items []*LiveChatModerator `json:"items,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "youtube#liveChatModeratorListResponse".
	Kind string `json:"kind,omitempty"`

	// NextPageToken: The token that can be used as the value of the
	// pageToken parameter to retrieve the next page in the result set.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// PageInfo: General pagination information.
	PageInfo *PageInfo `json:"pageInfo,omitempty"`

	// PrevPageToken: The token that can be used as the value of the
	// pageToken parameter to retrieve the previous page in the result set.
	PrevPageToken string `json:"prevPageToken,omitempty"`

	TokenPagination *TokenPagination `json:"tokenPagination,omitempty"`

	// VisitorId: The visitorId identifies the visitor.
	VisitorId string `json:"visitorId,omitempty"`

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

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

type LiveChatModeratorSnippet struct {
	// LiveChatId: The ID of the live chat this moderator can act on.
	LiveChatId string `json:"liveChatId,omitempty"`

	// ModeratorDetails: Details about the moderator.
	ModeratorDetails *ChannelProfileDetails `json:"moderatorDetails,omitempty"`

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

type LiveChatSuperChatDetails struct {
	// AmountDisplayString: A rendered string that displays the fund amount
	// and currency to the user.
	AmountDisplayString string `json:"amountDisplayString,omitempty"`

	// AmountMicros: The amount purchased by the user, in micros (1,750,000
	// micros = 1.75).
	AmountMicros uint64 `json:"amountMicros,omitempty,string"`

	// Currency: The currency in which the purchase was made.
	Currency string `json:"currency,omitempty"`

	// Tier: The tier in which the amount belongs. Lower amounts belong to
	// lower tiers. The lowest tier is 1.
	Tier int64 `json:"tier,omitempty"`

	// UserComment: The comment added by the user to this Super Chat event.
	UserComment string `json:"userComment,omitempty"`

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

type LiveChatSuperStickerDetails struct {
	// AmountDisplayString: A rendered string that displays the fund amount
	// and currency to the user.
	AmountDisplayString string `json:"amountDisplayString,omitempty"`

	// AmountMicros: The amount purchased by the user, in micros (1,750,000
	// micros = 1.75).
	AmountMicros uint64 `json:"amountMicros,omitempty,string"`

	// Currency: The currency in which the purchase was made.
	Currency string `json:"currency,omitempty"`

	// SuperStickerMetadata: Information about the Super Sticker.
	SuperStickerMetadata *SuperStickerMetadata `json:"superStickerMetadata,omitempty"`

	// Tier: The tier in which the amount belongs. Lower amounts belong to
	// lower tiers. The lowest tier is 1.
	Tier int64 `json:"tier,omitempty"`

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

type LiveChatTextMessageDetails struct {
	// MessageText: The user's message.
	MessageText string `json:"messageText,omitempty"`

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

type LiveChatUserBannedMessageDetails struct {
	// BanDurationSeconds: The duration of the ban. This property is only
	// present if the banType is temporary.
	BanDurationSeconds uint64 `json:"banDurationSeconds,omitempty,string"`

	// BanType: The type of ban.
	//
	// Possible values:
	//   "permanent"
	//   "temporary"
	BanType string `json:"banType,omitempty"`

	// BannedUserDetails: The details of the user that was banned.
	BannedUserDetails *ChannelProfileDetails `json:"bannedUserDetails,omitempty"`

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

// LiveStream: A live stream describes a live ingestion point.
type LiveStream struct {
	// Cdn: The cdn object defines the live stream's content delivery
	// network (CDN) settings. These settings provide details about the
	// manner in which you stream your content to YouTube.
	Cdn *CdnSettings `json:"cdn,omitempty"`

	// ContentDetails: The content_details object contains information about
	// the stream, including the closed captions ingestion URL.
	ContentDetails *LiveStreamContentDetails `json:"contentDetails,omitempty"`

	// Etag: Etag of this resource.
	Etag string `json:"etag,omitempty"`

	// Id: The ID that YouTube assigns to uniquely identify the stream.
	Id string `json:"id,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "youtube#liveStream".
	Kind string `json:"kind,omitempty"`

	// Snippet: The snippet object contains basic details about the stream,
	// including its channel, title, and description.
	Snippet *LiveStreamSnippet `json:"snippet,omitempty"`

	// Status: The status object contains information about live stream's
	// status.
	Status *LiveStreamStatus `json:"status,omitempty"`

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

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

type LiveStreamConfigurationIssue struct {
	// Description: The long-form description of the issue and how to
	// resolve it.
	Description string `json:"description,omitempty"`

	// Reason: The short-form reason for this issue.
	Reason string `json:"reason,omitempty"`

	// Severity: How severe this issue is to the stream.
	//
	// Possible values:
	//   "info"
	//   "warning"
	//   "error"
	Severity string `json:"severity,omitempty"`

	// Type: The kind of error happening.
	//
	// Possible values:
	//   "gopSizeOver"
	//   "gopSizeLong"
	//   "gopSizeShort"
	//   "openGop"
	//   "badContainer"
	//   "audioBitrateHigh"
	//   "audioBitrateLow"
	//   "audioSampleRate"
	//   "bitrateHigh"
	//   "bitrateLow"
	//   "audioCodec"
	//   "videoCodec"
	//   "noAudioStream"
	//   "noVideoStream"
	//   "multipleVideoStreams"
	//   "multipleAudioStreams"
	//   "audioTooManyChannels"
	//   "interlacedVideo"
	//   "frameRateHigh"
	//   "resolutionMismatch"
	//   "videoCodecMismatch"
	//   "videoInterlaceMismatch"
	//   "videoProfileMismatch"
	//   "videoBitrateMismatch"
	//   "framerateMismatch"
	//   "gopMismatch"
	//   "audioSampleRateMismatch"
	//   "audioStereoMismatch"
	//   "audioCodecMismatch"
	//   "audioBitrateMismatch"
	//   "videoResolutionSuboptimal"
	//   "videoResolutionUnsupported"
	//   "videoIngestionStarved"
	//   "videoIngestionFasterThanRealtime"
	Type string `json:"type,omitempty"`

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

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

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

// LiveStreamContentDetails: Detailed settings of a stream.
type LiveStreamContentDetails struct {
	// ClosedCaptionsIngestionUrl: The ingestion URL where the closed
	// captions of this stream are sent.
	ClosedCaptionsIngestionUrl string `json:"closedCaptionsIngestionUrl,omitempty"`

	// IsReusable: Indicates whether the stream is reusable, which means
	// that it can be bound to multiple broadcasts. It is common for
	// broadcasters to reuse the same stream for many different broadcasts
	// if those broadcasts occur at different times. If you set this value
	// to false, then the stream will not be reusable, which means that it
	// can only be bound to one broadcast. Non-reusable streams differ from
	// reusable streams in the following ways: - A non-reusable stream can
	// only be bound to one broadcast. - A non-reusable stream might be
	// deleted by an automated process after the broadcast ends. - The
	// liveStreams.list method does not list non-reusable streams if you
	// call the method and set the mine parameter to true. The only way to
	// use that method to retrieve the resource for a non-reusable stream is
	// to use the id parameter to identify the stream.
	IsReusable bool `json:"isReusable,omitempty"`

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

type LiveStreamHealthStatus struct {
	// ConfigurationIssues: The configurations issues on this stream
	ConfigurationIssues []*LiveStreamConfigurationIssue `json:"configurationIssues,omitempty"`

	// LastUpdateTimeSeconds: The last time this status was updated (in
	// seconds)
	LastUpdateTimeSeconds uint64 `json:"lastUpdateTimeSeconds,omitempty,string"`

	// Status: The status code of this stream
	//
	// Possible values:
	//   "good"
	//   "ok"
	//   "bad"
	//   "noData"
	//   "revoked"
	Status string `json:"status,omitempty"`

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

type LiveStreamListResponse struct {
	// Etag: Etag of this resource.
	Etag string `json:"etag,omitempty"`

	// EventId: Serialized EventId of the request which produced this
	// response.
	EventId string `json:"eventId,omitempty"`

	// Items: A list of live streams that match the request criteria.
	Items []*LiveStream `json:"items,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "youtube#liveStreamListResponse".
	Kind string `json:"kind,omitempty"`

	// NextPageToken: The token that can be used as the value of the
	// pageToken parameter to retrieve the next page in the result set.
	NextPageToken string `json:"nextPageToken,omitempty"`

	PageInfo *PageInfo `json:"pageInfo,omitempty"`

	// PrevPageToken: The token that can be used as the value of the
	// pageToken parameter to retrieve the previous page in the result set.
	PrevPageToken string `json:"prevPageToken,omitempty"`

	TokenPagination *TokenPagination `json:"tokenPagination,omitempty"`

	// VisitorId: The visitorId identifies the visitor.
	VisitorId string `json:"visitorId,omitempty"`

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

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

type LiveStreamSnippet struct {
	// ChannelId: The ID that YouTube uses to uniquely identify the channel
	// that is transmitting the stream.
	ChannelId string `json:"channelId,omitempty"`

	// Description: The stream's description. The value cannot be longer
	// than 10000 characters.
	Description string `json:"description,omitempty"`

	IsDefaultStream bool `json:"isDefaultStream,omitempty"`

	// PublishedAt: The date and time that the stream was created. The value
	// is specified in ISO 8601 format.
	PublishedAt string `json:"publishedAt,omitempty"`

	// Title: The stream's title. The value must be between 1 and 128
	// characters long.
	Title string `json:"title,omitempty"`

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

// LiveStreamStatus: Brief description of the live stream status.
type LiveStreamStatus struct {
	// HealthStatus: The health status of the stream.
	HealthStatus *LiveStreamHealthStatus `json:"healthStatus,omitempty"`

	// Possible values:
	//   "created"
	//   "ready"
	//   "active"
	//   "inactive"
	//   "error"
	StreamStatus string `json:"streamStatus,omitempty"`

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

type LocalizedProperty struct {
	Default string `json:"default,omitempty"`

	// DefaultLanguage: The language of the default property.
	DefaultLanguage *LanguageTag `json:"defaultLanguage,omitempty"`

	Localized []*LocalizedString `json:"localized,omitempty"`

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

type LocalizedString struct {
	Language string `json:"language,omitempty"`

	Value string `json:"value,omitempty"`

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

// Member: A *member* resource represents a member for a YouTube
// channel. A member provides recurring monetary support to a creator
// and receives special benefits.
type Member struct {
	// Etag: Etag of this resource.
	Etag string `json:"etag,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "youtube#member".
	Kind string `json:"kind,omitempty"`

	// Snippet: The snippet object contains basic details about the member.
	Snippet *MemberSnippet `json:"snippet,omitempty"`

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

type MemberListResponse struct {
	// Etag: Etag of this resource.
	Etag string `json:"etag,omitempty"`

	// EventId: Serialized EventId of the request which produced this
	// response.
	EventId string `json:"eventId,omitempty"`

	// Items: A list of members that match the request criteria.
	Items []*Member `json:"items,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "youtube#memberListResponse".
	Kind string `json:"kind,omitempty"`

	// NextPageToken: The token that can be used as the value of the
	// pageToken parameter to retrieve the next page in the result set.
	NextPageToken string `json:"nextPageToken,omitempty"`

	PageInfo *PageInfo `json:"pageInfo,omitempty"`

	TokenPagination *TokenPagination `json:"tokenPagination,omitempty"`

	// VisitorId: The visitorId identifies the visitor.
	VisitorId string `json:"visitorId,omitempty"`

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

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

type MemberSnippet struct {
	// CreatorChannelId: The id of the channel that's offering memberships.
	CreatorChannelId string `json:"creatorChannelId,omitempty"`

	// MemberDetails: Details about the member.
	MemberDetails *ChannelProfileDetails `json:"memberDetails,omitempty"`

	// MembershipsDetails: Details about the user's membership.
	MembershipsDetails *MembershipsDetails `json:"membershipsDetails,omitempty"`

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

type MembershipsDetails struct {
	// AccessibleLevels: Ids of all levels that the user has access to. This
	// includes the currently active level and all other levels that are
	// included because of a higher purchase.
	AccessibleLevels []string `json:"accessibleLevels,omitempty"`

	// HighestAccessibleLevel: Id of the highest level that the user has
	// access to at the moment.
	HighestAccessibleLevel string `json:"highestAccessibleLevel,omitempty"`

	// HighestAccessibleLevelDisplayName: Display name for the highest level
	// that the user has access to at the moment.
	HighestAccessibleLevelDisplayName string `json:"highestAccessibleLevelDisplayName,omitempty"`

	// MembershipsDuration: Data about memberships duration without taking
	// into consideration pricing levels.
	MembershipsDuration *MembershipsDuration `json:"membershipsDuration,omitempty"`

	// MembershipsDurationAtLevels: Data about memberships duration on
	// particular pricing levels.
	MembershipsDurationAtLevels []*MembershipsDurationAtLevel `json:"membershipsDurationAtLevels,omitempty"`

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

type MembershipsDuration struct {
	// MemberSince: The date and time when the user became a continuous
	// member across all levels.
	MemberSince string `json:"memberSince,omitempty"`

	// MemberTotalDurationMonths: The cumulative time the user has been a
	// member across all levels in complete months (the time is rounded down
	// to the nearest integer).
	MemberTotalDurationMonths int64 `json:"memberTotalDurationMonths,omitempty"`

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

type MembershipsDurationAtLevel struct {
	// Level: Pricing level ID.
	Level string `json:"level,omitempty"`

	// MemberSince: The date and time when the user became a continuous
	// member for the given level.
	MemberSince string `json:"memberSince,omitempty"`

	// MemberTotalDurationMonths: The cumulative time the user has been a
	// member for the given level in complete months (the time is rounded
	// down to the nearest integer).
	MemberTotalDurationMonths int64 `json:"memberTotalDurationMonths,omitempty"`

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

// MembershipsLevel: A *membershipsLevel* resource represents an offer
// made by YouTube creators for their fans. Users can become members of
// the channel by joining one of the available levels. They will provide
// recurring monetary support and receives special benefits.
type MembershipsLevel struct {
	// Etag: Etag of this resource.
	Etag string `json:"etag,omitempty"`

	// Id: The ID that YouTube assigns to uniquely identify the memberships
	// level.
	Id string `json:"id,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "youtube#membershipsLevelListResponse".
	Kind string `json:"kind,omitempty"`

	// Snippet: The snippet object contains basic details about the level.
	Snippet *MembershipsLevelSnippet `json:"snippet,omitempty"`

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

type MembershipsLevelListResponse struct {
	// Etag: Etag of this resource.
	Etag string `json:"etag,omitempty"`

	// EventId: Serialized EventId of the request which produced this
	// response.
	EventId string `json:"eventId,omitempty"`

	// Items: A list of pricing levels offered by a creator to the fans.
	Items []*MembershipsLevel `json:"items,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "youtube#membershipsLevelListResponse".
	Kind string `json:"kind,omitempty"`

	// VisitorId: The visitorId identifies the visitor.
	VisitorId string `json:"visitorId,omitempty"`

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

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

type MembershipsLevelSnippet struct {
	// CreatorChannelId: The id of the channel that's offering channel
	// memberships.
	CreatorChannelId string `json:"creatorChannelId,omitempty"`

	// LevelDetails: Details about the pricing level.
	LevelDetails *LevelDetails `json:"levelDetails,omitempty"`

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

// MonitorStreamInfo: Settings and Info of the monitor stream
type MonitorStreamInfo struct {
	// BroadcastStreamDelayMs: If you have set the enableMonitorStream
	// property to true, then this property determines the length of the
	// live broadcast delay.
	BroadcastStreamDelayMs int64 `json:"broadcastStreamDelayMs,omitempty"`

	// EmbedHtml: HTML code that embeds a player that plays the monitor
	// stream.
	EmbedHtml string `json:"embedHtml,omitempty"`

	// EnableMonitorStream: This value determines whether the monitor stream
	// is enabled for the broadcast. If the monitor stream is enabled, then
	// YouTube will broadcast the event content on a special stream intended
	// only for the broadcaster's consumption. The broadcaster can use the
	// stream to review the event content and also to identify the optimal
	// times to insert cuepoints. You need to set this value to true if you
	// intend to have a broadcast delay for your event. *Note:* This
	// property cannot be updated once the broadcast is in the testing or
	// live state.
	EnableMonitorStream *bool `json:"enableMonitorStream,omitempty"`

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

// PageInfo: Paging details for lists of resources, including total
// number of items available and number of resources returned in a
// single page.
type PageInfo struct {
	// ResultsPerPage: The number of results included in the API response.
	ResultsPerPage int64 `json:"resultsPerPage,omitempty"`

	// TotalResults: The total number of results in the result set.
	TotalResults int64 `json:"totalResults,omitempty"`

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

// Playlist: A *playlist* resource represents a YouTube playlist. A
// playlist is a collection of videos that can be viewed sequentially
// and shared with other users. A playlist can contain up to 200 videos,
// and YouTube does not limit the number of playlists that each user
// creates. By default, playlists are publicly visible to other users,
// but playlists can be public or private. YouTube also uses playlists
// to identify special collections of videos for a channel, such as: -
// uploaded videos - favorite videos - positively rated (liked) videos -
// watch history - watch later To be more specific, these lists are
// associated with a channel, which is a collection of a person, group,
// or company's videos, playlists, and other YouTube information. You
// can retrieve the playlist IDs for each of these lists from the
// channel resource for a given channel. You can then use the
// playlistItems.list method to retrieve any of those lists. You can
// also add or remove items from those lists by calling the
// playlistItems.insert and playlistItems.delete methods.
type Playlist struct {
	// ContentDetails: The contentDetails object contains information like
	// video count.
	ContentDetails *PlaylistContentDetails `json:"contentDetails,omitempty"`

	// Etag: Etag of this resource.
	Etag string `json:"etag,omitempty"`

	// Id: The ID that YouTube uses to uniquely identify the playlist.
	Id string `json:"id,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "youtube#playlist".
	Kind string `json:"kind,omitempty"`

	// Localizations: Localizations for different languages
	Localizations map[string]PlaylistLocalization `json:"localizations,omitempty"`

	// Player: The player object contains information that you would use to
	// play the playlist in an embedded player.
	Player *PlaylistPlayer `json:"player,omitempty"`

	// Snippet: The snippet object contains basic details about the
	// playlist, such as its title and description.
	Snippet *PlaylistSnippet `json:"snippet,omitempty"`

	// Status: The status object contains status information for the
	// playlist.
	Status *PlaylistStatus `json:"status,omitempty"`

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

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

type PlaylistContentDetails struct {
	// ItemCount: The number of videos in the playlist.
	ItemCount int64 `json:"itemCount,omitempty"`

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

// PlaylistItem: A *playlistItem* resource identifies another resource,
// such as a video, that is included in a playlist. In addition, the
// playlistItem resource contains details about the included resource
// that pertain specifically to how that resource is used in that
// playlist. YouTube uses playlists to identify special collections of
// videos for a channel, such as: - uploaded videos - favorite videos -
// positively rated (liked) videos - watch history - watch later To be
// more specific, these lists are associated with a channel, which is a
// collection of a person, group, or company's videos, playlists, and
// other YouTube information. You can retrieve the playlist IDs for each
// of these lists from the channel resource for a given channel. You can
// then use the playlistItems.list method to retrieve any of those
// lists. You can also add or remove items from those lists by calling
// the playlistItems.insert and playlistItems.delete methods. For
// example, if a user gives a positive rating to a video, you would
// insert that video into the liked videos playlist for that user's
// channel.
type PlaylistItem struct {
	// ContentDetails: The contentDetails object is included in the resource
	// if the included item is a YouTube video. The object contains
	// additional information about the video.
	ContentDetails *PlaylistItemContentDetails `json:"contentDetails,omitempty"`

	// Etag: Etag of this resource.
	Etag string `json:"etag,omitempty"`

	// Id: The ID that YouTube uses to uniquely identify the playlist item.
	Id string `json:"id,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "youtube#playlistItem".
	Kind string `json:"kind,omitempty"`

	// Snippet: The snippet object contains basic details about the playlist
	// item, such as its title and position in the playlist.
	Snippet *PlaylistItemSnippet `json:"snippet,omitempty"`

	// Status: The status object contains information about the playlist
	// item's privacy status.
	Status *PlaylistItemStatus `json:"status,omitempty"`

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

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

type PlaylistItemContentDetails struct {
	// EndAt: The time, measured in seconds from the start of the video,
	// when the video should stop playing. (The playlist owner can specify
	// the times when the video should start and stop playing when the video
	// is played in the context of the playlist.) By default, assume that
	// the video.endTime is the end of the video.
	EndAt string `json:"endAt,omitempty"`

	// Note: A user-generated note for this item.
	Note string `json:"note,omitempty"`

	// StartAt: The time, measured in seconds from the start of the video,
	// when the video should start playing. (The playlist owner can specify
	// the times when the video should start and stop playing when the video
	// is played in the context of the playlist.) The default value is 0.
	StartAt string `json:"startAt,omitempty"`

	// VideoId: The ID that YouTube uses to uniquely identify a video. To
	// retrieve the video resource, set the id query parameter to this value
	// in your API request.
	VideoId string `json:"videoId,omitempty"`

	// VideoPublishedAt: The date and time that the video was published to
	// YouTube. The value is specified in ISO 8601 format.
	VideoPublishedAt string `json:"videoPublishedAt,omitempty"`

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

type PlaylistItemListResponse struct {
	Etag string `json:"etag,omitempty"`

	// EventId: Serialized EventId of the request which produced this
	// response.
	EventId string `json:"eventId,omitempty"`

	// Items: A list of playlist items that match the request criteria.
	Items []*PlaylistItem `json:"items,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "youtube#playlistItemListResponse". Etag of this resource.
	Kind string `json:"kind,omitempty"`

	// NextPageToken: The token that can be used as the value of the
	// pageToken parameter to retrieve the next page in the result set.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// PageInfo: General pagination information.
	PageInfo *PageInfo `json:"pageInfo,omitempty"`

	// PrevPageToken: The token that can be used as the value of the
	// pageToken parameter to retrieve the previous page in the result set.
	PrevPageToken string `json:"prevPageToken,omitempty"`

	TokenPagination *TokenPagination `json:"tokenPagination,omitempty"`

	// VisitorId: The visitorId identifies the visitor.
	VisitorId string `json:"visitorId,omitempty"`

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

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

// PlaylistItemSnippet: Basic details about a playlist, including title,
// description and thumbnails. Basic details of a YouTube Playlist item
// provided by the author. Next ID: 13
type PlaylistItemSnippet struct {
	// ChannelId: The ID that YouTube uses to uniquely identify the user
	// that added the item to the playlist.
	ChannelId string `json:"channelId,omitempty"`

	// ChannelTitle: Channel title for the channel that the playlist item
	// belongs to.
	ChannelTitle string `json:"channelTitle,omitempty"`

	// Description: The item's description.
	Description string `json:"description,omitempty"`

	// PlaylistId: The ID that YouTube uses to uniquely identify thGe
	// playlist that the playlist item is in.
	PlaylistId string `json:"playlistId,omitempty"`

	// Position: The order in which the item appears in the playlist. The
	// value uses a zero-based index, so the first item has a position of 0,
	// the second item has a position of 1, and so forth.
	Position int64 `json:"position,omitempty"`

	// PublishedAt: The date and time that the item was added to the
	// playlist. The value is specified in ISO 8601 format.
	PublishedAt string `json:"publishedAt,omitempty"`

	// ResourceId: The id object contains information that can be used to
	// uniquely identify the resource that is included in the playlist as
	// the playlist item.
	ResourceId *ResourceId `json:"resourceId,omitempty"`

	// Thumbnails: A map of thumbnail images associated with the playlist
	// item. For each object in the map, the key is the name of the
	// thumbnail image, and the value is an object that contains other
	// information about the thumbnail.
	Thumbnails *ThumbnailDetails `json:"thumbnails,omitempty"`

	// Title: The item's title.
	Title string `json:"title,omitempty"`

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

// PlaylistItemStatus: Information about the playlist item's privacy
// status.
type PlaylistItemStatus struct {
	// PrivacyStatus: This resource's privacy status.
	//
	// Possible values:
	//   "public"
	//   "unlisted"
	//   "private"
	PrivacyStatus string `json:"privacyStatus,omitempty"`

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

type PlaylistListResponse struct {
	// Etag: Etag of this resource.
	Etag string `json:"etag,omitempty"`

	// EventId: Serialized EventId of the request which produced this
	// response.
	EventId string `json:"eventId,omitempty"`

	// Items: A list of playlists that match the request criteria
	Items []*Playlist `json:"items,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "youtube#playlistListResponse".
	Kind string `json:"kind,omitempty"`

	// NextPageToken: The token that can be used as the value of the
	// pageToken parameter to retrieve the next page in the result set.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// PageInfo: General pagination information.
	PageInfo *PageInfo `json:"pageInfo,omitempty"`

	// PrevPageToken: The token that can be used as the value of the
	// pageToken parameter to retrieve the previous page in the result set.
	PrevPageToken string `json:"prevPageToken,omitempty"`

	TokenPagination *TokenPagination `json:"tokenPagination,omitempty"`

	// VisitorId: The visitorId identifies the visitor.
	VisitorId string `json:"visitorId,omitempty"`

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

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

// PlaylistLocalization: Playlist localization setting
type PlaylistLocalization struct {
	// Description: The localized strings for playlist's description.
	Description string `json:"description,omitempty"`

	// Title: The localized strings for playlist's title.
	Title string `json:"title,omitempty"`

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

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

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

type PlaylistPlayer struct {
	// EmbedHtml: An <iframe> tag that embeds a player that will play the
	// playlist.
	EmbedHtml string `json:"embedHtml,omitempty"`

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

// PlaylistSnippet: Basic details about a playlist, including title,
// description and thumbnails.
type PlaylistSnippet struct {
	// ChannelId: The ID that YouTube uses to uniquely identify the channel
	// that published the playlist.
	ChannelId string `json:"channelId,omitempty"`

	// ChannelTitle: The channel title of the channel that the video belongs
	// to.
	ChannelTitle string `json:"channelTitle,omitempty"`

	// DefaultLanguage: The language of the playlist's default title and
	// description.
	DefaultLanguage string `json:"defaultLanguage,omitempty"`

	// Description: The playlist's description.
	Description string `json:"description,omitempty"`

	// Localized: Localized title and description, read-only.
	Localized *PlaylistLocalization `json:"localized,omitempty"`

	// PublishedAt: The date and time that the playlist was created. The
	// value is specified in ISO 8601 format.
	PublishedAt string `json:"publishedAt,omitempty"`

	// Tags: Keyword tags associated with the playlist.
	Tags []string `json:"tags,omitempty"`

	// Thumbnails: A map of thumbnail images associated with the playlist.
	// For each object in the map, the key is the name of the thumbnail
	// image, and the value is an object that contains other information
	// about the thumbnail.
	Thumbnails *ThumbnailDetails `json:"thumbnails,omitempty"`

	// Title: The playlist's title.
	Title string `json:"title,omitempty"`

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

type PlaylistStatus struct {
	// PrivacyStatus: The playlist's privacy status.
	//
	// Possible values:
	//   "public"
	//   "unlisted"
	//   "private"
	PrivacyStatus string `json:"privacyStatus,omitempty"`

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

// PromotedItem: Describes a single promoted item.
type PromotedItem struct {
	// CustomMessage: A custom message to display for this promotion. This
	// field is currently ignored unless the promoted item is a website.
	CustomMessage string `json:"customMessage,omitempty"`

	// Id: Identifies the promoted item.
	Id *PromotedItemId `json:"id,omitempty"`

	// PromotedByContentOwner: If true, the content owner's name will be
	// used when displaying the promotion. This field can only be set when
	// the update is made on behalf of the content owner.
	PromotedByContentOwner bool `json:"promotedByContentOwner,omitempty"`

	// Timing: The temporal position within the video where the promoted
	// item will be displayed. If present, it overrides the default timing.
	Timing *InvideoTiming `json:"timing,omitempty"`

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

// PromotedItemId: Describes a single promoted item id. It is a union of
// various possible types.
type PromotedItemId struct {
	// RecentlyUploadedBy: If type is recentUpload, this field identifies
	// the channel from which to take the recent upload. If missing, the
	// channel is assumed to be the same channel for which the
	// invideoPromotion is set.
	RecentlyUploadedBy string `json:"recentlyUploadedBy,omitempty"`

	// Type: Describes the type of the promoted item.
	//
	// Possible values:
	//   "video"
	//   "website"
	//   "recentUpload"
	Type string `json:"type,omitempty"`

	// VideoId: If the promoted item represents a video, this field
	// represents the unique YouTube ID identifying it. This field will be
	// present only if type has the value video.
	VideoId string `json:"videoId,omitempty"`

	// WebsiteUrl: If the promoted item represents a website, this field
	// represents the url pointing to the website. This field will be
	// present only if type has the value website.
	WebsiteUrl string `json:"websiteUrl,omitempty"`

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

// PropertyValue: A pair Property / Value.
type PropertyValue struct {
	// Property: A property.
	Property string `json:"property,omitempty"`

	// Value: The property's value.
	Value string `json:"value,omitempty"`

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

type RelatedEntity struct {
	Entity *Entity `json:"entity,omitempty"`

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

// ResourceId: A resource id is a generic reference that points to
// another YouTube resource.
type ResourceId struct {
	// ChannelId: The ID that YouTube uses to uniquely identify the referred
	// resource, if that resource is a channel. This property is only
	// present if the resourceId.kind value is youtube#channel.
	ChannelId string `json:"channelId,omitempty"`

	// Kind: The type of the API resource.
	Kind string `json:"kind,omitempty"`

	// PlaylistId: The ID that YouTube uses to uniquely identify the
	// referred resource, if that resource is a playlist. This property is
	// only present if the resourceId.kind value is youtube#playlist.
	PlaylistId string `json:"playlistId,omitempty"`

	// VideoId: The ID that YouTube uses to uniquely identify the referred
	// resource, if that resource is a video. This property is only present
	// if the resourceId.kind value is youtube#video.
	VideoId string `json:"videoId,omitempty"`

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

type SearchListResponse struct {
	// Etag: Etag of this resource.
	Etag string `json:"etag,omitempty"`

	// EventId: Serialized EventId of the request which produced this
	// response.
	EventId string `json:"eventId,omitempty"`

	// Items: Pagination information for token pagination.
	Items []*SearchResult `json:"items,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "youtube#searchListResponse".
	Kind string `json:"kind,omitempty"`

	// NextPageToken: The token that can be used as the value of the
	// pageToken parameter to retrieve the next page in the result set.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// PageInfo: General pagination information.
	PageInfo *PageInfo `json:"pageInfo,omitempty"`

	// PrevPageToken: The token that can be used as the value of the
	// pageToken parameter to retrieve the previous page in the result set.
	PrevPageToken string `json:"prevPageToken,omitempty"`

	RegionCode string `json:"regionCode,omitempty"`

	TokenPagination *TokenPagination `json:"tokenPagination,omitempty"`

	// VisitorId: The visitorId identifies the visitor.
	VisitorId string `json:"visitorId,omitempty"`

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

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

// SearchResult: A search result contains information about a YouTube
// video, channel, or playlist that matches the search parameters
// specified in an API request. While a search result points to a
// uniquely identifiable resource, like a video, it does not have its
// own persistent data.
type SearchResult struct {
	// Etag: Etag of this resource.
	Etag string `json:"etag,omitempty"`

	// Id: The id object contains information that can be used to uniquely
	// identify the resource that matches the search request.
	Id *ResourceId `json:"id,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "youtube#searchResult".
	Kind string `json:"kind,omitempty"`

	// Snippet: The snippet object contains basic details about a search
	// result, such as its title or description. For example, if the search
	// result is a video, then the title will be the video's title and the
	// description will be the video's description.
	Snippet *SearchResultSnippet `json:"snippet,omitempty"`

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

// SearchResultSnippet: Basic details about a search result, including
// title, description and thumbnails of the item referenced by the
// search result.
type SearchResultSnippet struct {
	// ChannelId: The value that YouTube uses to uniquely identify the
	// channel that published the resource that the search result
	// identifies.
	ChannelId string `json:"channelId,omitempty"`

	// ChannelTitle: The title of the channel that published the resource
	// that the search result identifies.
	ChannelTitle string `json:"channelTitle,omitempty"`

	// Description: A description of the search result.
	Description string `json:"description,omitempty"`

	// LiveBroadcastContent: It indicates if the resource (video or channel)
	// has upcoming/active live broadcast content. Or it's "none" if there
	// is not any upcoming/active live broadcasts.
	//
	// Possible values:
	//   "none"
	//   "upcoming"
	//   "live"
	//   "completed"
	LiveBroadcastContent string `json:"liveBroadcastContent,omitempty"`

	// PublishedAt: The creation date and time of the resource that the
	// search result identifies. The value is specified in ISO 8601 format.
	PublishedAt string `json:"publishedAt,omitempty"`

	// Thumbnails: A map of thumbnail images associated with the search
	// result. For each object in the map, the key is the name of the
	// thumbnail image, and the value is an object that contains other
	// information about the thumbnail.
	Thumbnails *ThumbnailDetails `json:"thumbnails,omitempty"`

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

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

// Sponsor: A `__sponsor__` resource represents a sponsor for a YouTube
// channel. A sponsor provides recurring monetary support to a creator
// and receives special benefits.
type Sponsor struct {
	// Etag: Etag of this resource.
	Etag string `json:"etag,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "youtube#sponsor".
	Kind string `json:"kind,omitempty"`

	// Snippet: The `snippet` object contains basic details about the
	// sponsor.
	Snippet *SponsorSnippet `json:"snippet,omitempty"`

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

type SponsorListResponse struct {
	// Etag: Etag of this resource.
	Etag string `json:"etag,omitempty"`

	// EventId: Serialized EventId of the request which produced this
	// response.
	EventId string `json:"eventId,omitempty"`

	// Items: A list of sponsors that match the request criteria.
	Items []*Sponsor `json:"items,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "youtube#sponsorListResponse".
	Kind string `json:"kind,omitempty"`

	// NextPageToken: The token that can be used as the value of the
	// `pageToken` parameter to retrieve the next page in the result set.
	NextPageToken string `json:"nextPageToken,omitempty"`

	PageInfo *PageInfo `json:"pageInfo,omitempty"`

	TokenPagination *TokenPagination `json:"tokenPagination,omitempty"`

	// VisitorId: The `visitorId` identifies the visitor.
	VisitorId string `json:"visitorId,omitempty"`

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

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

type SponsorSnippet struct {
	// ChannelId: The id of the channel being sponsored.
	ChannelId string `json:"channelId,omitempty"`

	// CumulativeDurationMonths: The cumulative time a user has been a
	// sponsor in months.
	CumulativeDurationMonths int64 `json:"cumulativeDurationMonths,omitempty"`

	// SponsorDetails: Details about the sponsor.
	SponsorDetails *ChannelProfileDetails `json:"sponsorDetails,omitempty"`

	// SponsorSince: The date and time when the user became a sponsor. The
	// value is specified in ISO 8601 (`YYYY-MM-DDThh:mm:ss.sZ`) format.
	SponsorSince string `json:"sponsorSince,omitempty"`

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

// Subscription: A *subscription* resource contains information about a
// YouTube user subscription. A subscription notifies a user when new
// videos are added to a channel or when another user takes one of
// several actions on YouTube, such as uploading a video, rating a
// video, or commenting on a video.
type Subscription struct {
	// ContentDetails: The contentDetails object contains basic statistics
	// about the subscription.
	ContentDetails *SubscriptionContentDetails `json:"contentDetails,omitempty"`

	// Etag: Etag of this resource.
	Etag string `json:"etag,omitempty"`

	// Id: The ID that YouTube uses to uniquely identify the subscription.
	Id string `json:"id,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "youtube#subscription".
	Kind string `json:"kind,omitempty"`

	// Snippet: The snippet object contains basic details about the
	// subscription, including its title and the channel that the user
	// subscribed to.
	Snippet *SubscriptionSnippet `json:"snippet,omitempty"`

	// SubscriberSnippet: The subscriberSnippet object contains basic
	// details about the subscriber.
	SubscriberSnippet *SubscriptionSubscriberSnippet `json:"subscriberSnippet,omitempty"`

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

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

// SubscriptionContentDetails: Details about the content to witch a
// subscription refers.
type SubscriptionContentDetails struct {
	// ActivityType: The type of activity this subscription is for (only
	// uploads, everything).
	//
	// Possible values:
	//   "subscriptionActivityTypeUnspecified"
	//   "all"
	//   "uploads"
	ActivityType string `json:"activityType,omitempty"`

	// NewItemCount: The number of new items in the subscription since its
	// content was last read.
	NewItemCount int64 `json:"newItemCount,omitempty"`

	// TotalItemCount: The approximate number of items that the subscription
	// points to.
	TotalItemCount int64 `json:"totalItemCount,omitempty"`

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

type SubscriptionListResponse struct {
	// Etag: Etag of this resource.
	Etag string `json:"etag,omitempty"`

	// EventId: Serialized EventId of the request which produced this
	// response.
	EventId string `json:"eventId,omitempty"`

	// Items: A list of subscriptions that match the request criteria.
	Items []*Subscription `json:"items,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "youtube#subscriptionListResponse".
	Kind string `json:"kind,omitempty"`

	// NextPageToken: The token that can be used as the value of the
	// pageToken parameter to retrieve the next page in the result set.
	NextPageToken string `json:"nextPageToken,omitempty"`

	PageInfo *PageInfo `json:"pageInfo,omitempty"`

	// PrevPageToken: The token that can be used as the value of the
	// pageToken parameter to retrieve the previous page in the result set.
	PrevPageToken string `json:"prevPageToken,omitempty"`

	TokenPagination *TokenPagination `json:"tokenPagination,omitempty"`

	// VisitorId: The visitorId identifies the visitor.
	VisitorId string `json:"visitorId,omitempty"`

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

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

// SubscriptionSnippet: Basic details about a subscription, including
// title, description and thumbnails of the subscribed item.
type SubscriptionSnippet struct {
	// ChannelId: The ID that YouTube uses to uniquely identify the
	// subscriber's channel.
	ChannelId string `json:"channelId,omitempty"`

	// ChannelTitle: Channel title for the channel that the subscription
	// belongs to.
	ChannelTitle string `json:"channelTitle,omitempty"`

	// Description: The subscription's details.
	Description string `json:"description,omitempty"`

	// PublishedAt: The date and time that the subscription was created. The
	// value is specified in ISO 8601 format.
	PublishedAt string `json:"publishedAt,omitempty"`

	// ResourceId: The id object contains information about the channel that
	// the user subscribed to.
	ResourceId *ResourceId `json:"resourceId,omitempty"`

	// Thumbnails: A map of thumbnail images associated with the video. For
	// each object in the map, the key is the name of the thumbnail image,
	// and the value is an object that contains other information about the
	// thumbnail.
	Thumbnails *ThumbnailDetails `json:"thumbnails,omitempty"`

	// Title: The subscription's title.
	Title string `json:"title,omitempty"`

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

// SubscriptionSubscriberSnippet: Basic details about a subscription's
// subscriber including title, description, channel ID and thumbnails.
type SubscriptionSubscriberSnippet struct {
	// ChannelId: The channel ID of the subscriber.
	ChannelId string `json:"channelId,omitempty"`

	// Description: The description of the subscriber.
	Description string `json:"description,omitempty"`

	// Thumbnails: Thumbnails for this subscriber.
	Thumbnails *ThumbnailDetails `json:"thumbnails,omitempty"`

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

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

// SuperChatEvent: A `__superChatEvent__` resource represents a Super
// Chat purchase on a YouTube channel.
type SuperChatEvent struct {
	// Etag: Etag of this resource.
	Etag string `json:"etag,omitempty"`

	// Id: The ID that YouTube assigns to uniquely identify the Super Chat
	// event.
	Id string `json:"id,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "youtube#superChatEvent".
	Kind string `json:"kind,omitempty"`

	// Snippet: The `snippet` object contains basic details about the Super
	// Chat event.
	Snippet *SuperChatEventSnippet `json:"snippet,omitempty"`

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

type SuperChatEventListResponse struct {
	// Etag: Etag of this resource.
	Etag string `json:"etag,omitempty"`

	// EventId: Serialized EventId of the request which produced this
	// response.
	EventId string `json:"eventId,omitempty"`

	// Items: A list of Super Chat purchases that match the request
	// criteria.
	Items []*SuperChatEvent `json:"items,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "youtube#superChatEventListResponse".
	Kind string `json:"kind,omitempty"`

	// NextPageToken: The token that can be used as the value of the
	// pageToken parameter to retrieve the next page in the result set.
	NextPageToken string `json:"nextPageToken,omitempty"`

	PageInfo *PageInfo `json:"pageInfo,omitempty"`

	TokenPagination *TokenPagination `json:"tokenPagination,omitempty"`

	// VisitorId: The visitorId identifies the visitor.
	VisitorId string `json:"visitorId,omitempty"`

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

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

type SuperChatEventSnippet struct {
	// AmountMicros: The purchase amount, in micros of the purchase
	// currency. e.g., 1 is represented as 1000000.
	AmountMicros uint64 `json:"amountMicros,omitempty,string"`

	// ChannelId: Channel id where the event occurred.
	ChannelId string `json:"channelId,omitempty"`

	// CommentText: The text contents of the comment left by the user.
	CommentText string `json:"commentText,omitempty"`

	// CreatedAt: The date and time when the event occurred. The value is
	// specified in ISO 8601 format.
	CreatedAt string `json:"createdAt,omitempty"`

	// Currency: The currency in which the purchase was made. ISO 4217.
	Currency string `json:"currency,omitempty"`

	// DisplayString: A rendered string that displays the purchase amount
	// and currency (e.g., "$1.00"). The string is rendered for the given
	// language.
	DisplayString string `json:"displayString,omitempty"`

	// IsSuperStickerEvent: True if this event is a Super Sticker event.
	IsSuperStickerEvent bool `json:"isSuperStickerEvent,omitempty"`

	// MessageType: The tier for the paid message, which is based on the
	// amount of money spent to purchase the message.
	MessageType int64 `json:"messageType,omitempty"`

	// SuperStickerMetadata: If this event is a Super Sticker event, this
	// field will contain metadata about the Super Sticker.
	SuperStickerMetadata *SuperStickerMetadata `json:"superStickerMetadata,omitempty"`

	// SupporterDetails: Details about the supporter.
	SupporterDetails *ChannelProfileDetails `json:"supporterDetails,omitempty"`

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

type SuperStickerMetadata struct {
	// AltText: Internationalized alt text that describes the sticker image
	// and any animation associated with it.
	AltText string `json:"altText,omitempty"`

	// AltTextLanguage: Specifies the localization language in which the alt
	// text is returned.
	AltTextLanguage string `json:"altTextLanguage,omitempty"`

	// StickerId: Unique identifier of the Super Sticker. This is a shorter
	// form of the alt_text that includes pack name and a recognizable
	// characteristic of the sticker.
	StickerId string `json:"stickerId,omitempty"`

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

type TestItem struct {
	Gaia int64 `json:"gaia,omitempty,string"`

	Id string `json:"id,omitempty"`

	Snippet *TestItemTestItemSnippet `json:"snippet,omitempty"`

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

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

type TestItemTestItemSnippet struct {
}

// ThirdPartyLink: A *third party account link* resource represents a
// link between a YouTube account or a channel and an account on a
// third-party service.
type ThirdPartyLink struct {
	// Etag: Etag of this resource
	Etag string `json:"etag,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "youtube#thirdPartyLink".
	Kind string `json:"kind,omitempty"`

	// LinkingToken: The linking_token identifies a YouTube account and
	// channel with which the third party account is linked.
	LinkingToken string `json:"linkingToken,omitempty"`

	// Snippet: The snippet object contains basic details about the third-
	// party account link.
	Snippet *ThirdPartyLinkSnippet `json:"snippet,omitempty"`

	// Status: The status object contains information about the status of
	// the link.
	Status *ThirdPartyLinkStatus `json:"status,omitempty"`

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

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

// ThirdPartyLinkSnippet: Basic information about a third party account
// link, including its type and type-specific information.
type ThirdPartyLinkSnippet struct {
	// ChannelToStoreLink: Information specific to a link between a channel
	// and a store on a merchandising platform.
	ChannelToStoreLink *ChannelToStoreLinkDetails `json:"channelToStoreLink,omitempty"`

	// Type: Type of the link named after the entities that are being
	// linked.
	//
	// Possible values:
	//   "linkUnspecified"
	//   "channelToStoreLink" - A link that is connecting (or about to
	// connect) a channel with a store on a merchandising platform in order
	// to enable retail commerce capabilities for that channel on YouTube.
	Type string `json:"type,omitempty"`

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

// ThirdPartyLinkStatus: The third-party link status object contains
// information about the status of the link.
type ThirdPartyLinkStatus struct {
	// Possible values:
	//   "unknown"
	//   "failed"
	//   "pending"
	//   "linked"
	LinkStatus string `json:"linkStatus,omitempty"`

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

// Thumbnail: A thumbnail is an image representing a YouTube resource.
type Thumbnail struct {
	// Height: (Optional) Height of the thumbnail image.
	Height int64 `json:"height,omitempty"`

	// Url: The thumbnail image's URL.
	Url string `json:"url,omitempty"`

	// Width: (Optional) Width of the thumbnail image.
	Width int64 `json:"width,omitempty"`

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

// ThumbnailDetails: Internal representation of thumbnails for a YouTube
// resource.
type ThumbnailDetails struct {
	// Default: The default image for this resource.
	Default *Thumbnail `json:"default,omitempty"`

	// High: The high quality image for this resource.
	High *Thumbnail `json:"high,omitempty"`

	// Maxres: The maximum resolution quality image for this resource.
	Maxres *Thumbnail `json:"maxres,omitempty"`

	// Medium: The medium quality image for this resource.
	Medium *Thumbnail `json:"medium,omitempty"`

	// Standard: The standard quality image for this resource.
	Standard *Thumbnail `json:"standard,omitempty"`

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

type ThumbnailSetResponse struct {
	// Etag: Etag of this resource.
	Etag string `json:"etag,omitempty"`

	// EventId: Serialized EventId of the request which produced this
	// response.
	EventId string `json:"eventId,omitempty"`

	// Items: A list of thumbnails.
	Items []*ThumbnailDetails `json:"items,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "youtube#thumbnailSetResponse".
	Kind string `json:"kind,omitempty"`

	// VisitorId: The visitorId identifies the visitor.
	VisitorId string `json:"visitorId,omitempty"`

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

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

// TokenPagination: Stub token pagination template to suppress results.
type TokenPagination struct {
}

// Video: A *video* resource represents a YouTube video.
type Video struct {
	// AgeGating: Age restriction details related to a video. This data can
	// only be retrieved by the video owner.
	AgeGating *VideoAgeGating `json:"ageGating,omitempty"`

	// ContentDetails: The contentDetails object contains information about
	// the video content, including the length of the video and its aspect
	// ratio.
	ContentDetails *VideoContentDetails `json:"contentDetails,omitempty"`

	// Etag: Etag of this resource.
	Etag string `json:"etag,omitempty"`

	// FileDetails: The fileDetails object encapsulates information about
	// the video file that was uploaded to YouTube, including the file's
	// resolution, duration, audio and video codecs, stream bitrates, and
	// more. This data can only be retrieved by the video owner.
	FileDetails *VideoFileDetails `json:"fileDetails,omitempty"`

	// Id: The ID that YouTube uses to uniquely identify the video.
	Id string `json:"id,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "youtube#video".
	Kind string `json:"kind,omitempty"`

	// LiveStreamingDetails: The liveStreamingDetails object contains
	// metadata about a live video broadcast. The object will only be
	// present in a video resource if the video is an upcoming, live, or
	// completed live broadcast.
	LiveStreamingDetails *VideoLiveStreamingDetails `json:"liveStreamingDetails,omitempty"`

	// Localizations: The localizations object contains localized versions
	// of the basic details about the video, such as its title and
	// description.
	Localizations map[string]VideoLocalization `json:"localizations,omitempty"`

	// MonetizationDetails: The monetizationDetails object encapsulates
	// information about the monetization status of the video.
	MonetizationDetails *VideoMonetizationDetails `json:"monetizationDetails,omitempty"`

	// Player: The player object contains information that you would use to
	// play the video in an embedded player.
	Player *VideoPlayer `json:"player,omitempty"`

	// ProcessingDetails: The processingDetails object encapsulates
	// information about YouTube's progress in processing the uploaded video
	// file. The properties in the object identify the current processing
	// status and an estimate of the time remaining until YouTube finishes
	// processing the video. This part also indicates whether different
	// types of data or content, such as file details or thumbnail images,
	// are available for the video. The processingProgress object is
	// designed to be polled so that the video uploaded can track the
	// progress that YouTube has made in processing the uploaded video file.
	// This data can only be retrieved by the video owner.
	ProcessingDetails *VideoProcessingDetails `json:"processingDetails,omitempty"`

	// ProjectDetails: The projectDetails object contains information about
	// the project specific video metadata.
	ProjectDetails *VideoProjectDetails `json:"projectDetails,omitempty"`

	// RecordingDetails: The recordingDetails object encapsulates
	// information about the location, date and address where the video was
	// recorded.
	RecordingDetails *VideoRecordingDetails `json:"recordingDetails,omitempty"`

	// Snippet: The snippet object contains basic details about the video,
	// such as its title, description, and category.
	Snippet *VideoSnippet `json:"snippet,omitempty"`

	// Statistics: The statistics object contains statistics about the
	// video.
	Statistics *VideoStatistics `json:"statistics,omitempty"`

	// Status: The status object contains information about the video's
	// uploading, processing, and privacy statuses.
	Status *VideoStatus `json:"status,omitempty"`

	// Suggestions: The suggestions object encapsulates suggestions that
	// identify opportunities to improve the video quality or the metadata
	// for the uploaded video. This data can only be retrieved by the video
	// owner.
	Suggestions *VideoSuggestions `json:"suggestions,omitempty"`

	// TopicDetails: The topicDetails object encapsulates information about
	// Freebase topics associated with the video.
	TopicDetails *VideoTopicDetails `json:"topicDetails,omitempty"`

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

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

type VideoAbuseReport struct {
	// Comments: Additional comments regarding the abuse report.
	Comments string `json:"comments,omitempty"`

	// Language: The language that the content was viewed in.
	Language string `json:"language,omitempty"`

	// ReasonId: The high-level, or primary, reason that the content is
	// abusive. The value is an abuse report reason ID.
	ReasonId string `json:"reasonId,omitempty"`

	// SecondaryReasonId: The specific, or secondary, reason that this
	// content is abusive (if available). The value is an abuse report
	// reason ID that is a valid secondary reason for the primary reason.
	SecondaryReasonId string `json:"secondaryReasonId,omitempty"`

	// VideoId: The ID that YouTube uses to uniquely identify the video.
	VideoId string `json:"videoId,omitempty"`

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

// VideoAbuseReportReason: A `__videoAbuseReportReason__` resource
// identifies a reason that a video could be reported as abusive. Video
// abuse report reasons are used with `video.ReportAbuse`.
type VideoAbuseReportReason struct {
	// Etag: Etag of this resource.
	Etag string `json:"etag,omitempty"`

	// Id: The ID of this abuse report reason.
	Id string `json:"id,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "youtube#videoAbuseReportReason".
	Kind string `json:"kind,omitempty"`

	// Snippet: The `snippet` object contains basic details about the abuse
	// report reason.
	Snippet *VideoAbuseReportReasonSnippet `json:"snippet,omitempty"`

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

type VideoAbuseReportReasonListResponse struct {
	// Etag: Etag of this resource.
	Etag string `json:"etag,omitempty"`

	// EventId: Serialized EventId of the request which produced this
	// response.
	EventId string `json:"eventId,omitempty"`

	// Items: A list of valid abuse reasons that are used with
	// `video.ReportAbuse`.
	Items []*VideoAbuseReportReason `json:"items,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "youtube#videoAbuseReportReasonListResponse".
	Kind string `json:"kind,omitempty"`

	// VisitorId: The `visitorId` identifies the visitor.
	VisitorId string `json:"visitorId,omitempty"`

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

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

// VideoAbuseReportReasonSnippet: Basic details about a video category,
// such as its localized title.
type VideoAbuseReportReasonSnippet struct {
	// Label: The localized label belonging to this abuse report reason.
	Label string `json:"label,omitempty"`

	// SecondaryReasons: The secondary reasons associated with this reason,
	// if any are available. (There might be 0 or more.)
	SecondaryReasons []*VideoAbuseReportSecondaryReason `json:"secondaryReasons,omitempty"`

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

type VideoAbuseReportSecondaryReason struct {
	// Id: The ID of this abuse report secondary reason.
	Id string `json:"id,omitempty"`

	// Label: The localized label for this abuse report secondary reason.
	Label string `json:"label,omitempty"`

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

type VideoAgeGating struct {
	// AlcoholContent: Indicates whether or not the video has alcoholic
	// beverage content. Only users of legal purchasing age in a particular
	// country, as identified by ICAP, can view the content.
	AlcoholContent bool `json:"alcoholContent,omitempty"`

	// Restricted: Age-restricted trailers. For redband trailers and
	// adult-rated video-games. Only users aged 18+ can view the content.
	// The the field is true the content is restricted to viewers aged 18+.
	// Otherwise The field won't be present.
	Restricted bool `json:"restricted,omitempty"`

	// VideoGameRating: Video game rating, if any.
	//
	// Possible values:
	//   "anyone"
	//   "m15Plus"
	//   "m16Plus"
	//   "m17Plus"
	VideoGameRating string `json:"videoGameRating,omitempty"`

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

// VideoCategory: A *videoCategory* resource identifies a category that
// has been or could be associated with uploaded videos.
type VideoCategory struct {
	// Etag: Etag of this resource.
	Etag string `json:"etag,omitempty"`

	// Id: The ID that YouTube uses to uniquely identify the video category.
	Id string `json:"id,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "youtube#videoCategory".
	Kind string `json:"kind,omitempty"`

	// Snippet: The snippet object contains basic details about the video
	// category, including its title.
	Snippet *VideoCategorySnippet `json:"snippet,omitempty"`

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

type VideoCategoryListResponse struct {
	// Etag: Etag of this resource.
	Etag string `json:"etag,omitempty"`

	// EventId: Serialized EventId of the request which produced this
	// response.
	EventId string `json:"eventId,omitempty"`

	// Items: A list of video categories that can be associated with YouTube
	// videos. In this map, the video category ID is the map key, and its
	// value is the corresponding videoCategory resource.
	Items []*VideoCategory `json:"items,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "youtube#videoCategoryListResponse".
	Kind string `json:"kind,omitempty"`

	// NextPageToken: The token that can be used as the value of the
	// pageToken parameter to retrieve the next page in the result set.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// PageInfo: General pagination information.
	PageInfo *PageInfo `json:"pageInfo,omitempty"`

	// PrevPageToken: The token that can be used as the value of the
	// pageToken parameter to retrieve the previous page in the result set.
	PrevPageToken string `json:"prevPageToken,omitempty"`

	TokenPagination *TokenPagination `json:"tokenPagination,omitempty"`

	// VisitorId: The visitorId identifies the visitor.
	VisitorId string `json:"visitorId,omitempty"`

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

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

// VideoCategorySnippet: Basic details about a video category, such as
// its localized title.
type VideoCategorySnippet struct {
	Assignable bool `json:"assignable,omitempty"`

	// ChannelId: The YouTube channel that created the video category.
	ChannelId string `json:"channelId,omitempty"`

	// Title: The video category's title.
	Title string `json:"title,omitempty"`

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

// VideoContentDetails: Details about the content of a YouTube Video.
type VideoContentDetails struct {
	// Caption: The value of captions indicates whether the video has
	// captions or not.
	//
	// Possible values:
	//   "true"
	//   "false"
	Caption string `json:"caption,omitempty"`

	// ContentRating: Specifies the ratings that the video received under
	// various rating schemes.
	ContentRating *ContentRating `json:"contentRating,omitempty"`

	// CountryRestriction: The countryRestriction object contains
	// information about the countries where a video is (or is not)
	// viewable.
	CountryRestriction *AccessPolicy `json:"countryRestriction,omitempty"`

	// Definition: The value of definition indicates whether the video is
	// available in high definition or only in standard definition.
	//
	// Possible values:
	//   "sd" - sd
	//   "hd" - hd
	Definition string `json:"definition,omitempty"`

	// Dimension: The value of dimension indicates whether the video is
	// available in 3D or in 2D.
	Dimension string `json:"dimension,omitempty"`

	// Duration: The length of the video. The tag value is an ISO 8601
	// duration in the format PT#M#S, in which the letters PT indicate that
	// the value specifies a period of time, and the letters M and S refer
	// to length in minutes and seconds, respectively. The # characters
	// preceding the M and S letters are both integers that specify the
	// number of minutes (or seconds) of the video. For example, a value of
	// PT15M51S indicates that the video is 15 minutes and 51 seconds long.
	Duration string `json:"duration,omitempty"`

	// HasCustomThumbnail: Indicates whether the video uploader has provided
	// a custom thumbnail image for the video. This property is only visible
	// to the video uploader.
	HasCustomThumbnail bool `json:"hasCustomThumbnail,omitempty"`

	// LicensedContent: The value of is_license_content indicates whether
	// the video is licensed content.
	LicensedContent bool `json:"licensedContent,omitempty"`

	// Projection: Specifies the projection format of the video.
	//
	// Possible values:
	//   "rectangular"
	//   "360"
	Projection string `json:"projection,omitempty"`

	// RegionRestriction: The regionRestriction object contains information
	// about the countries where a video is (or is not) viewable. The object
	// will contain either the contentDetails.regionRestriction.allowed
	// property or the contentDetails.regionRestriction.blocked property.
	RegionRestriction *VideoContentDetailsRegionRestriction `json:"regionRestriction,omitempty"`

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

// VideoContentDetailsRegionRestriction: DEPRECATED Region restriction
// of the video.
type VideoContentDetailsRegionRestriction struct {
	// Allowed: A list of region codes that identify countries where the
	// video is viewable. If this property is present and a country is not
	// listed in its value, then the video is blocked from appearing in that
	// country. If this property is present and contains an empty list, the
	// video is blocked in all countries.
	Allowed []string `json:"allowed,omitempty"`

	// Blocked: A list of region codes that identify countries where the
	// video is blocked. If this property is present and a country is not
	// listed in its value, then the video is viewable in that country. If
	// this property is present and contains an empty list, the video is
	// viewable in all countries.
	Blocked []string `json:"blocked,omitempty"`

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

// VideoFileDetails: Describes original video file properties, including
// technical details about audio and video streams, but also metadata
// information like content length, digitization time, or geotagging
// information.
type VideoFileDetails struct {
	// AudioStreams: A list of audio streams contained in the uploaded video
	// file. Each item in the list contains detailed metadata about an audio
	// stream.
	AudioStreams []*VideoFileDetailsAudioStream `json:"audioStreams,omitempty"`

	// BitrateBps: The uploaded video file's combined (video and audio)
	// bitrate in bits per second.
	BitrateBps uint64 `json:"bitrateBps,omitempty,string"`

	// Container: The uploaded video file's container format.
	Container string `json:"container,omitempty"`

	// CreationTime: The date and time when the uploaded video file was
	// created. The value is specified in ISO 8601 format. Currently, the
	// following ISO 8601 formats are supported: - Date only: YYYY-MM-DD -
	// Naive time: YYYY-MM-DDTHH:MM:SS - Time with timezone:
	// YYYY-MM-DDTHH:MM:SS+HH:MM
	CreationTime string `json:"creationTime,omitempty"`

	// DurationMs: The length of the uploaded video in milliseconds.
	DurationMs uint64 `json:"durationMs,omitempty,string"`

	// FileName: The uploaded file's name. This field is present whether a
	// video file or another type of file was uploaded.
	FileName string `json:"fileName,omitempty"`

	// FileSize: The uploaded file's size in bytes. This field is present
	// whether a video file or another type of file was uploaded.
	FileSize uint64 `json:"fileSize,omitempty,string"`

	// FileType: The uploaded file's type as detected by YouTube's video
	// processing engine. Currently, YouTube only processes video files, but
	// this field is present whether a video file or another type of file
	// was uploaded.
	//
	// Possible values:
	//   "video" - Known video file (e.g., an MP4 file).
	//   "audio" - Audio only file (e.g., an MP3 file).
	//   "image" - Image file (e.g., a JPEG image).
	//   "archive" - Archive file (e.g., a ZIP archive).
	//   "document" - Document or text file (e.g., MS Word document).
	//   "project" - Movie project file (e.g., Microsoft Windows Movie Maker
	// project).
	//   "other" - Other non-video file type.
	FileType string `json:"fileType,omitempty"`

	// VideoStreams: A list of video streams contained in the uploaded video
	// file. Each item in the list contains detailed metadata about a video
	// stream.
	VideoStreams []*VideoFileDetailsVideoStream `json:"videoStreams,omitempty"`

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

// VideoFileDetailsAudioStream: Information about an audio stream.
type VideoFileDetailsAudioStream struct {
	// BitrateBps: The audio stream's bitrate, in bits per second.
	BitrateBps uint64 `json:"bitrateBps,omitempty,string"`

	// ChannelCount: The number of audio channels that the stream contains.
	ChannelCount int64 `json:"channelCount,omitempty"`

	// Codec: The audio codec that the stream uses.
	Codec string `json:"codec,omitempty"`

	// Vendor: A value that uniquely identifies a video vendor. Typically,
	// the value is a four-letter vendor code.
	Vendor string `json:"vendor,omitempty"`

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

// VideoFileDetailsVideoStream: Information about a video stream.
type VideoFileDetailsVideoStream struct {
	// AspectRatio: The video content's display aspect ratio, which
	// specifies the aspect ratio in which the video should be displayed.
	AspectRatio float64 `json:"aspectRatio,omitempty"`

	// BitrateBps: The video stream's bitrate, in bits per second.
	BitrateBps uint64 `json:"bitrateBps,omitempty,string"`

	// Codec: The video codec that the stream uses.
	Codec string `json:"codec,omitempty"`

	// FrameRateFps: The video stream's frame rate, in frames per second.
	FrameRateFps float64 `json:"frameRateFps,omitempty"`

	// HeightPixels: The encoded video content's height in pixels.
	HeightPixels int64 `json:"heightPixels,omitempty"`

	// Rotation: The amount that YouTube needs to rotate the original source
	// content to properly display the video.
	//
	// Possible values:
	//   "none"
	//   "clockwise"
	//   "upsideDown"
	//   "counterClockwise"
	//   "other"
	Rotation string `json:"rotation,omitempty"`

	// Vendor: A value that uniquely identifies a video vendor. Typically,
	// the value is a four-letter vendor code.
	Vendor string `json:"vendor,omitempty"`

	// WidthPixels: The encoded video content's width in pixels. You can
	// calculate the video's encoding aspect ratio as width_pixels /
	// height_pixels.
	WidthPixels int64 `json:"widthPixels,omitempty"`

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

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

type VideoListResponse struct {
	// Etag: Etag of this resource.
	Etag string `json:"etag,omitempty"`

	// EventId: Serialized EventId of the request which produced this
	// response.
	EventId string `json:"eventId,omitempty"`

	Items []*Video `json:"items,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "youtube#videoListResponse".
	Kind string `json:"kind,omitempty"`

	// NextPageToken: The token that can be used as the value of the
	// pageToken parameter to retrieve the next page in the result set.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// PageInfo: General pagination information.
	PageInfo *PageInfo `json:"pageInfo,omitempty"`

	// PrevPageToken: The token that can be used as the value of the
	// pageToken parameter to retrieve the previous page in the result set.
	PrevPageToken string `json:"prevPageToken,omitempty"`

	TokenPagination *TokenPagination `json:"tokenPagination,omitempty"`

	// VisitorId: The visitorId identifies the visitor.
	VisitorId string `json:"visitorId,omitempty"`

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

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

// VideoLiveStreamingDetails: Details about the live streaming metadata.
type VideoLiveStreamingDetails struct {
	// ActiveLiveChatId: The ID of the currently active live chat attached
	// to this video. This field is filled only if the video is a currently
	// live broadcast that has live chat. Once the broadcast transitions to
	// complete this field will be removed and the live chat closed down.
	// For persistent broadcasts that live chat id will no longer be tied to
	// this video but rather to the new video being displayed at the
	// persistent page.
	ActiveLiveChatId string `json:"activeLiveChatId,omitempty"`

	// ActualEndTime: The time that the broadcast actually ended. The value
	// is specified in ISO 8601 format. This value will not be available
	// until the broadcast is over.
	ActualEndTime string `json:"actualEndTime,omitempty"`

	// ActualStartTime: The time that the broadcast actually started. The
	// value is specified in ISO 8601 format. This value will not be
	// available until the broadcast begins.
	ActualStartTime string `json:"actualStartTime,omitempty"`

	// ConcurrentViewers: The number of viewers currently watching the
	// broadcast. The property and its value will be present if the
	// broadcast has current viewers and the broadcast owner has not hidden
	// the viewcount for the video. Note that YouTube stops tracking the
	// number of concurrent viewers for a broadcast when the broadcast ends.
	// So, this property would not identify the number of viewers watching
	// an archived video of a live broadcast that already ended.
	ConcurrentViewers uint64 `json:"concurrentViewers,omitempty,string"`

	// ScheduledEndTime: The time that the broadcast is scheduled to end.
	// The value is specified in ISO 8601 format. If the value is empty or
	// the property is not present, then the broadcast is scheduled to
	// continue indefinitely.
	ScheduledEndTime string `json:"scheduledEndTime,omitempty"`

	// ScheduledStartTime: The time that the broadcast is scheduled to
	// begin. The value is specified in ISO 8601 format.
	ScheduledStartTime string `json:"scheduledStartTime,omitempty"`

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

// VideoLocalization: Localized versions of certain video properties
// (e.g. title).
type VideoLocalization struct {
	// Description: Localized version of the video's description.
	Description string `json:"description,omitempty"`

	// Title: Localized version of the video's title.
	Title string `json:"title,omitempty"`

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

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

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

// VideoMonetizationDetails: Details about monetization of a YouTube
// Video.
type VideoMonetizationDetails struct {
	// Access: The value of access indicates whether the video can be
	// monetized or not.
	Access *AccessPolicy `json:"access,omitempty"`

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

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

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

// VideoPlayer: Player to be used for a video playback.
type VideoPlayer struct {
	EmbedHeight int64 `json:"embedHeight,omitempty,string"`

	// EmbedHtml: An <iframe> tag that embeds a player that will play the
	// video.
	EmbedHtml string `json:"embedHtml,omitempty"`

	// EmbedWidth: The embed width
	EmbedWidth int64 `json:"embedWidth,omitempty,string"`

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

// VideoProcessingDetails: Describes processing status and progress and
// availability of some other Video resource parts.
type VideoProcessingDetails struct {
	// EditorSuggestionsAvailability: This value indicates whether video
	// editing suggestions, which might improve video quality or the
	// playback experience, are available for the video. You can retrieve
	// these suggestions by requesting the suggestions part in your
	// videos.list() request.
	EditorSuggestionsAvailability string `json:"editorSuggestionsAvailability,omitempty"`

	// FileDetailsAvailability: This value indicates whether file details
	// are available for the uploaded video. You can retrieve a video's file
	// details by requesting the fileDetails part in your videos.list()
	// request.
	FileDetailsAvailability string `json:"fileDetailsAvailability,omitempty"`

	// ProcessingFailureReason: The reason that YouTube failed to process
	// the video. This property will only have a value if the
	// processingStatus property's value is failed.
	//
	// Possible values:
	//   "uploadFailed"
	//   "transcodeFailed"
	//   "streamingFailed"
	//   "other"
	ProcessingFailureReason string `json:"processingFailureReason,omitempty"`

	// ProcessingIssuesAvailability: This value indicates whether the video
	// processing engine has generated suggestions that might improve
	// YouTube's ability to process the the video, warnings that explain
	// video processing problems, or errors that cause video processing
	// problems. You can retrieve these suggestions by requesting the
	// suggestions part in your videos.list() request.
	ProcessingIssuesAvailability string `json:"processingIssuesAvailability,omitempty"`

	// ProcessingProgress: The processingProgress object contains
	// information about the progress YouTube has made in processing the
	// video. The values are really only relevant if the video's processing
	// status is processing.
	ProcessingProgress *VideoProcessingDetailsProcessingProgress `json:"processingProgress,omitempty"`

	// ProcessingStatus: The video's processing status. This value indicates
	// whether YouTube was able to process the video or if the video is
	// still being processed.
	//
	// Possible values:
	//   "processing"
	//   "succeeded"
	//   "failed"
	//   "terminated"
	ProcessingStatus string `json:"processingStatus,omitempty"`

	// TagSuggestionsAvailability: This value indicates whether keyword
	// (tag) suggestions are available for the video. Tags can be added to a
	// video's metadata to make it easier for other users to find the video.
	// You can retrieve these suggestions by requesting the suggestions part
	// in your videos.list() request.
	TagSuggestionsAvailability string `json:"tagSuggestionsAvailability,omitempty"`

	// ThumbnailsAvailability: This value indicates whether thumbnail images
	// have been generated for the video.
	ThumbnailsAvailability string `json:"thumbnailsAvailability,omitempty"`

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

// VideoProcessingDetailsProcessingProgress: Video processing progress
// and completion time estimate.
type VideoProcessingDetailsProcessingProgress struct {
	// PartsProcessed: The number of parts of the video that YouTube has
	// already processed. You can estimate the percentage of the video that
	// YouTube has already processed by calculating: 100 * parts_processed /
	// parts_total Note that since the estimated number of parts could
	// increase without a corresponding increase in the number of parts that
	// have already been processed, it is possible that the calculated
	// progress could periodically decrease while YouTube processes a video.
	PartsProcessed uint64 `json:"partsProcessed,omitempty,string"`

	// PartsTotal: An estimate of the total number of parts that need to be
	// processed for the video. The number may be updated with more precise
	// estimates while YouTube processes the video.
	PartsTotal uint64 `json:"partsTotal,omitempty,string"`

	// TimeLeftMs: An estimate of the amount of time, in millseconds, that
	// YouTube needs to finish processing the video.
	TimeLeftMs uint64 `json:"timeLeftMs,omitempty,string"`

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

// VideoProjectDetails: Project specific details about the content of a
// YouTube Video.
type VideoProjectDetails struct {
	// Tags: A list of project tags associated with the video during the
	// upload.
	Tags []string `json:"tags,omitempty"`

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

// VideoRating: Basic details about rating of a video.
type VideoRating struct {
	// Rating: Rating of a video.
	//
	// Possible values:
	//   "none"
	//   "like"
	//   "dislike"
	Rating string `json:"rating,omitempty"`

	// VideoId: The ID that YouTube uses to uniquely identify the video.
	VideoId string `json:"videoId,omitempty"`

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

type VideoRatingListResponse struct {
	// Etag: Etag of this resource.
	Etag string `json:"etag,omitempty"`

	// EventId: Serialized EventId of the request which produced this
	// response.
	EventId string `json:"eventId,omitempty"`

	// Items: A list of ratings that match the request criteria.
	Items []*VideoRating `json:"items,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "youtube#videoGetRatingResponse".
	Kind string `json:"kind,omitempty"`

	// VisitorId: The visitorId identifies the visitor.
	VisitorId string `json:"visitorId,omitempty"`

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

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

// VideoRecordingDetails: Recording information associated with the
// video.
type VideoRecordingDetails struct {
	// Location: The geolocation information associated with the video.
	Location *GeoPoint `json:"location,omitempty"`

	// LocationDescription: The text description of the location where the
	// video was recorded.
	LocationDescription string `json:"locationDescription,omitempty"`

	// RecordingDate: The date and time when the video was recorded. The
	// value is specified in ISO 8601 (YYYY-MM-DDThh:mm:ss.sssZ) format.
	RecordingDate string `json:"recordingDate,omitempty"`

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

// VideoSnippet: Basic details about a video, including title,
// description, uploader, thumbnails and category.
type VideoSnippet struct {
	// CategoryId: The YouTube video category associated with the video.
	CategoryId string `json:"categoryId,omitempty"`

	// ChannelId: The ID that YouTube uses to uniquely identify the channel
	// that the video was uploaded to.
	ChannelId string `json:"channelId,omitempty"`

	// ChannelTitle: Channel title for the channel that the video belongs
	// to.
	ChannelTitle string `json:"channelTitle,omitempty"`

	// DefaultAudioLanguage: The default_audio_language property specifies
	// the language spoken in the video's default audio track.
	DefaultAudioLanguage string `json:"defaultAudioLanguage,omitempty"`

	// DefaultLanguage: The language of the videos's default snippet.
	DefaultLanguage string `json:"defaultLanguage,omitempty"`

	// Description: The video's description. @mutable youtube.videos.insert
	// youtube.videos.update
	Description string `json:"description,omitempty"`

	// LiveBroadcastContent: Indicates if the video is an upcoming/active
	// live broadcast. Or it's "none" if the video is not an upcoming/active
	// live broadcast.
	//
	// Possible values:
	//   "none"
	//   "upcoming"
	//   "live"
	//   "completed"
	LiveBroadcastContent string `json:"liveBroadcastContent,omitempty"`

	// Localized: Localized snippet selected with the hl parameter. If no
	// such localization exists, this field is populated with the default
	// snippet. (Read-only)
	Localized *VideoLocalization `json:"localized,omitempty"`

	// PublishedAt: The date and time that the video was uploaded. The value
	// is specified in ISO 8601 format.
	PublishedAt string `json:"publishedAt,omitempty"`

	// Tags: A list of keyword tags associated with the video. Tags may
	// contain spaces.
	Tags []string `json:"tags,omitempty"`

	// Thumbnails: A map of thumbnail images associated with the video. For
	// each object in the map, the key is the name of the thumbnail image,
	// and the value is an object that contains other information about the
	// thumbnail.
	Thumbnails *ThumbnailDetails `json:"thumbnails,omitempty"`

	// Title: The video's title. @mutable youtube.videos.insert
	// youtube.videos.update
	Title string `json:"title,omitempty"`

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

// VideoStatistics: Statistics about the video, such as the number of
// times the video was viewed or liked.
type VideoStatistics struct {
	// CommentCount: The number of comments for the video.
	CommentCount uint64 `json:"commentCount,omitempty,string"`

	// DislikeCount: The number of users who have indicated that they
	// disliked the video by giving it a negative rating.
	DislikeCount uint64 `json:"dislikeCount,omitempty,string"`

	// FavoriteCount: The number of users who currently have the video
	// marked as a favorite video.
	FavoriteCount uint64 `json:"favoriteCount,omitempty,string"`

	// LikeCount: The number of users who have indicated that they liked the
	// video by giving it a positive rating.
	LikeCount uint64 `json:"likeCount,omitempty,string"`

	// ViewCount: The number of times the video has been viewed.
	ViewCount uint64 `json:"viewCount,omitempty,string"`

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

// VideoStatus: Basic details about a video category, such as its
// localized title. Next Id: 17
type VideoStatus struct {
	// Embeddable: This value indicates if the video can be embedded on
	// another website. @mutable youtube.videos.insert youtube.videos.update
	Embeddable bool `json:"embeddable,omitempty"`

	// FailureReason: This value explains why a video failed to upload. This
	// property is only present if the uploadStatus property indicates that
	// the upload failed.
	//
	// Possible values:
	//   "conversion" - Unable to convert video content.
	//   "invalidFile" - Invalid file format.
	//   "emptyFile" - Empty file.
	//   "tooSmall" - File was too small.
	//   "codec" - Unsupported codec.
	//   "uploadAborted" - Upload wasn't finished.
	FailureReason string `json:"failureReason,omitempty"`

	// License: The video's license. @mutable youtube.videos.insert
	// youtube.videos.update
	//
	// Possible values:
	//   "youtube"
	//   "creativeCommon"
	License string `json:"license,omitempty"`

	MadeForKids bool `json:"madeForKids,omitempty"`

	// PrivacyStatus: The video's privacy status.
	//
	// Possible values:
	//   "public"
	//   "unlisted"
	//   "private"
	PrivacyStatus string `json:"privacyStatus,omitempty"`

	// PublicStatsViewable: This value indicates if the extended video
	// statistics on the watch page can be viewed by everyone. Note that the
	// view count, likes, etc will still be visible if this is disabled.
	// @mutable youtube.videos.insert youtube.videos.update
	PublicStatsViewable bool `json:"publicStatsViewable,omitempty"`

	// PublishAt: The date and time when the video is scheduled to publish.
	// It can be set only if the privacy status of the video is private. The
	// value is specified in ISO 8601 format.
	PublishAt string `json:"publishAt,omitempty"`

	// RejectionReason: This value explains why YouTube rejected an uploaded
	// video. This property is only present if the uploadStatus property
	// indicates that the upload was rejected.
	//
	// Possible values:
	//   "copyright" - Copyright infringement.
	//   "inappropriate" - Inappropriate video content.
	//   "duplicate" - Duplicate upload in the same channel.
	//   "termsOfUse" - Terms of use violation.
	//   "uploaderAccountSuspended" - Uploader account was suspended.
	//   "length" - Video duration was too long.
	//   "claim" - Blocked by content owner.
	//   "uploaderAccountClosed" - Uploader closed his/her account.
	//   "trademark" - Trademark infringement.
	//   "legal" - An unspecified legal reason.
	RejectionReason string `json:"rejectionReason,omitempty"`

	SelfDeclaredMadeForKids bool `json:"selfDeclaredMadeForKids,omitempty"`

	// UploadStatus: The status of the uploaded video.
	//
	// Possible values:
	//   "uploaded" - Video has been uploaded but not processed yet.
	//   "processed" - Video has been successfully processed.
	//   "failed" - Processing has failed. See FailureReason.
	//   "rejected" - Video has been rejected. See RejectionReason.
	//   "deleted" - Video has been deleted.
	UploadStatus string `json:"uploadStatus,omitempty"`

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

// VideoSuggestions: Specifies suggestions on how to improve video
// content, including encoding hints, tag suggestions, and editor
// suggestions.
type VideoSuggestions struct {
	// EditorSuggestions: A list of video editing operations that might
	// improve the video quality or playback experience of the uploaded
	// video.
	//
	// Possible values:
	//   "videoAutoLevels" - Picture brightness levels seem off and could be
	// corrected.
	//   "videoStabilize" - The video appears shaky and could be stabilized.
	//   "videoCrop" - Margins (mattes) detected around the picture could be
	// cropped.
	//   "audioQuietAudioSwap" - The audio track appears silent and could be
	// swapped with a better quality one.
	EditorSuggestions []string `json:"editorSuggestions,omitempty"`

	// ProcessingErrors: A list of errors that will prevent YouTube from
	// successfully processing the uploaded video video. These errors
	// indicate that, regardless of the video's current processing status,
	// eventually, that status will almost certainly be failed.
	//
	// Possible values:
	//   "audioFile" - File contains audio only (e.g., an MP3 file).
	//   "imageFile" - Image file (e.g., a JPEG image).
	//   "projectFile" - Movie project file (e.g., Microsoft Windows Movie
	// Maker project).
	//   "notAVideoFile" - Other non-video file.
	//   "docFile" - Document or text file (e.g., MS Word document).
	//   "archiveFile" - An archive file (e.g., a ZIP archive).
	//   "unsupportedSpatialAudioLayout" - Unsupported spatial audio layout
	// type.
	ProcessingErrors []string `json:"processingErrors,omitempty"`

	// ProcessingHints: A list of suggestions that may improve YouTube's
	// ability to process the video.
	//
	// Possible values:
	//   "nonStreamableMov" - The MP4 file is not streamable, this will slow
	// down the processing. MOOV atom was not found at the beginning of the
	// file.
	//   "sendBestQualityVideo" - Probably a better quality version of the
	// video exists. The video has wide screen aspect ratio, but is not an
	// HD video.
	//   "sphericalVideo" - Uploaded video is spherical video.
	//   "spatialAudio" - Uploaded video has spatial audio.
	//   "vrVideo" - Uploaded video is VR video.
	//   "hdrVideo" - Uploaded video is HDR video.
	ProcessingHints []string `json:"processingHints,omitempty"`

	// ProcessingWarnings: A list of reasons why YouTube may have difficulty
	// transcoding the uploaded video or that might result in an erroneous
	// transcoding. These warnings are generated before YouTube actually
	// processes the uploaded video file. In addition, they identify issues
	// that are unlikely to cause the video processing to fail but that
	// might cause problems such as sync issues, video artifacts, or a
	// missing audio track.
	//
	// Possible values:
	//   "unknownContainer" - Unrecognized file format, transcoding is
	// likely to fail.
	//   "unknownVideoCodec" - Unrecognized video codec, transcoding is
	// likely to fail.
	//   "unknownAudioCodec" - Unrecognized audio codec, transcoding is
	// likely to fail.
	//   "inconsistentResolution" - Conflicting container and stream
	// resolutions.
	//   "hasEditlist" - Edit lists are not currently supported.
	//   "problematicVideoCodec" - Video codec that is known to cause
	// problems was used.
	//   "problematicAudioCodec" - Audio codec that is known to cause
	// problems was used.
	//   "unsupportedVrStereoMode" - Unsupported VR video stereo mode.
	//   "unsupportedSphericalProjectionType" - Unsupported spherical video
	// projection type.
	//   "unsupportedHdrPixelFormat" - Unsupported HDR pixel format.
	//   "unsupportedHdrColorMetadata" - Unspecified HDR color metadata.
	//   "problematicHdrLookupTable" - Problematic HDR lookup table
	// attached.
	ProcessingWarnings []string `json:"processingWarnings,omitempty"`

	// TagSuggestions: A list of keyword tags that could be added to the
	// video's metadata to increase the likelihood that users will locate
	// your video when searching or browsing on YouTube.
	TagSuggestions []*VideoSuggestionsTagSuggestion `json:"tagSuggestions,omitempty"`

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

// VideoSuggestionsTagSuggestion: A single tag suggestion with it's
// relevance information.
type VideoSuggestionsTagSuggestion struct {
	// CategoryRestricts: A set of video categories for which the tag is
	// relevant. You can use this information to display appropriate tag
	// suggestions based on the video category that the video uploader
	// associates with the video. By default, tag suggestions are relevant
	// for all categories if there are no restricts defined for the keyword.
	CategoryRestricts []string `json:"categoryRestricts,omitempty"`

	// Tag: The keyword tag suggested for the video.
	Tag string `json:"tag,omitempty"`

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

// VideoTopicDetails: Freebase topic information related to the video.
type VideoTopicDetails struct {
	// RelevantTopicIds: Similar to topic_id, except that these topics are
	// merely relevant to the video. These are topics that may be mentioned
	// in, or appear in the video. You can retrieve information about each
	// topic using Freebase Topic API.
	RelevantTopicIds []string `json:"relevantTopicIds,omitempty"`

	// TopicCategories: A list of Wikipedia URLs that provide a high-level
	// description of the video's content.
	TopicCategories []string `json:"topicCategories,omitempty"`

	// TopicIds: A list of Freebase topic IDs that are centrally associated
	// with the video. These are topics that are centrally featured in the
	// video, and it can be said that the video is mainly about each of
	// these. You can retrieve information about each topic using the < a
	// href="http://wiki.freebase.com/wiki/Topic_API">Freebase Topic API.
	TopicIds []string `json:"topicIds,omitempty"`

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

// WatchSettings: Branding properties for the watch. All deprecated.
type WatchSettings struct {
	// BackgroundColor: The text color for the video watch page's branded
	// area.
	BackgroundColor string `json:"backgroundColor,omitempty"`

	// FeaturedPlaylistId: An ID that uniquely identifies a playlist that
	// displays next to the video player.
	FeaturedPlaylistId string `json:"featuredPlaylistId,omitempty"`

	// TextColor: The background color for the video watch page's branded
	// area.
	TextColor string `json:"textColor,omitempty"`

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

// method id "youtube.abuseReports.insert":

type AbuseReportsInsertCall struct {
	s           *Service
	abusereport *AbuseReport
	urlParams_  gensupport.URLParams
	ctx_        context.Context
	header_     http.Header
}

// Insert: Inserts a new resource into this collection.
func (r *AbuseReportsService) Insert(part []string, abusereport *AbuseReport) *AbuseReportsInsertCall {
	c := &AbuseReportsInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.urlParams_.SetMulti("part", append([]string{}, part...))
	c.abusereport = abusereport
	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 *AbuseReportsInsertCall) Fields(s ...googleapi.Field) *AbuseReportsInsertCall {
	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 *AbuseReportsInsertCall) Context(ctx context.Context) *AbuseReportsInsertCall {
	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 *AbuseReportsInsertCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AbuseReportsInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200912")
	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.abusereport)
	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, "youtube/v3/abuseReports")
	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 "youtube.abuseReports.insert" call.
// Exactly one of *AbuseReport or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *AbuseReport.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 *AbuseReportsInsertCall) Do(opts ...googleapi.CallOption) (*AbuseReport, 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 := &AbuseReport{
		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": "Inserts a new resource into this collection.",
	//   "flatPath": "youtube/v3/abuseReports",
	//   "httpMethod": "POST",
	//   "id": "youtube.abuseReports.insert",
	//   "parameterOrder": [
	//     "part"
	//   ],
	//   "parameters": {
	//     "part": {
	//       "description": "The *part* parameter serves two purposes in this operation. It identifies the properties that the write operation will set as well as the properties that the API response will include.",
	//       "location": "query",
	//       "repeated": true,
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "youtube/v3/abuseReports",
	//   "request": {
	//     "$ref": "AbuseReport"
	//   },
	//   "response": {
	//     "$ref": "AbuseReport"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/youtube",
	//     "https://www.googleapis.com/auth/youtube.force-ssl"
	//   ]
	// }

}

// method id "youtube.activities.list":

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

// List: Retrieves a list of resources, possibly filtered.
func (r *ActivitiesService) List(part []string) *ActivitiesListCall {
	c := &ActivitiesListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.urlParams_.SetMulti("part", append([]string{}, part...))
	return c
}

// ChannelId sets the optional parameter "channelId":
func (c *ActivitiesListCall) ChannelId(channelId string) *ActivitiesListCall {
	c.urlParams_.Set("channelId", channelId)
	return c
}

// Home sets the optional parameter "home":
func (c *ActivitiesListCall) Home(home bool) *ActivitiesListCall {
	c.urlParams_.Set("home", fmt.Sprint(home))
	return c
}

// MaxResults sets the optional parameter "maxResults": The *maxResults*
// parameter specifies the maximum number of items that should be
// returned in the result set.
func (c *ActivitiesListCall) MaxResults(maxResults int64) *ActivitiesListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// Mine sets the optional parameter "mine":
func (c *ActivitiesListCall) Mine(mine bool) *ActivitiesListCall {
	c.urlParams_.Set("mine", fmt.Sprint(mine))
	return c
}

// PageToken sets the optional parameter "pageToken": The *pageToken*
// parameter identifies a specific page in the result set that should be
// returned. In an API response, the nextPageToken and prevPageToken
// properties identify other pages that could be retrieved.
func (c *ActivitiesListCall) PageToken(pageToken string) *ActivitiesListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// PublishedAfter sets the optional parameter "publishedAfter":
func (c *ActivitiesListCall) PublishedAfter(publishedAfter string) *ActivitiesListCall {
	c.urlParams_.Set("publishedAfter", publishedAfter)
	return c
}

// PublishedBefore sets the optional parameter "publishedBefore":
func (c *ActivitiesListCall) PublishedBefore(publishedBefore string) *ActivitiesListCall {
	c.urlParams_.Set("publishedBefore", publishedBefore)
	return c
}

// RegionCode sets the optional parameter "regionCode":
func (c *ActivitiesListCall) RegionCode(regionCode string) *ActivitiesListCall {
	c.urlParams_.Set("regionCode", regionCode)
	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 *ActivitiesListCall) Fields(s ...googleapi.Field) *ActivitiesListCall {
	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 *ActivitiesListCall) IfNoneMatch(entityTag string) *ActivitiesListCall {
	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 *ActivitiesListCall) Context(ctx context.Context) *ActivitiesListCall {
	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 *ActivitiesListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ActivitiesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200912")
	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, "youtube/v3/activities")
	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 "youtube.activities.list" call.
// Exactly one of *ActivityListResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *ActivityListResponse.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 *ActivitiesListCall) Do(opts ...googleapi.CallOption) (*ActivityListResponse, 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 := &ActivityListResponse{
		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": "Retrieves a list of resources, possibly filtered.",
	//   "flatPath": "youtube/v3/activities",
	//   "httpMethod": "GET",
	//   "id": "youtube.activities.list",
	//   "parameterOrder": [
	//     "part"
	//   ],
	//   "parameters": {
	//     "channelId": {
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "home": {
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "maxResults": {
	//       "default": "5",
	//       "description": "The *maxResults* parameter specifies the maximum number of items that should be returned in the result set.",
	//       "format": "uint32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "mine": {
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "pageToken": {
	//       "description": "The *pageToken* parameter identifies a specific page in the result set that should be returned. In an API response, the nextPageToken and prevPageToken properties identify other pages that could be retrieved.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "part": {
	//       "description": "The *part* parameter specifies a comma-separated list of one or more activity resource properties that the API response will include. If the parameter identifies a property that contains child properties, the child properties will be included in the response. For example, in an activity resource, the snippet property contains other properties that identify the type of activity, a display title for the activity, and so forth. If you set *part=snippet*, the API response will also contain all of those nested properties.",
	//       "location": "query",
	//       "repeated": true,
	//       "required": true,
	//       "type": "string"
	//     },
	//     "publishedAfter": {
	//       "format": "google-datetime",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "publishedBefore": {
	//       "format": "google-datetime",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "regionCode": {
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "youtube/v3/activities",
	//   "response": {
	//     "$ref": "ActivityListResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/youtube",
	//     "https://www.googleapis.com/auth/youtube.force-ssl",
	//     "https://www.googleapis.com/auth/youtube.readonly"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *ActivitiesListCall) Pages(ctx context.Context, f func(*ActivityListResponse) 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 "youtube.captions.delete":

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

// Delete: Deletes a resource.
func (r *CaptionsService) Delete(id string) *CaptionsDeleteCall {
	c := &CaptionsDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.urlParams_.Set("id", id)
	return c
}

// OnBehalfOf sets the optional parameter "onBehalfOf": ID of the
// Google+ Page for the channel that the request is be on behalf of
func (c *CaptionsDeleteCall) OnBehalfOf(onBehalfOf string) *CaptionsDeleteCall {
	c.urlParams_.Set("onBehalfOf", onBehalfOf)
	return c
}

// OnBehalfOfContentOwner sets the optional parameter
// "onBehalfOfContentOwner": *Note:* This parameter is intended
// exclusively for YouTube content partners. The
// *onBehalfOfContentOwner* parameter indicates that the request's
// authorization credentials identify a YouTube CMS user who is acting
// on behalf of the content owner specified in the parameter value. This
// parameter is intended for YouTube content partners that own and
// manage many different YouTube channels. It allows content owners to
// authenticate once and get access to all their video and channel data,
// without having to provide authentication credentials for each
// individual channel. The actual CMS account that the user
// authenticates with must be linked to the specified YouTube content
// owner.
func (c *CaptionsDeleteCall) OnBehalfOfContentOwner(onBehalfOfContentOwner string) *CaptionsDeleteCall {
	c.urlParams_.Set("onBehalfOfContentOwner", onBehalfOfContentOwner)
	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 *CaptionsDeleteCall) Fields(s ...googleapi.Field) *CaptionsDeleteCall {
	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 *CaptionsDeleteCall) Context(ctx context.Context) *CaptionsDeleteCall {
	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 *CaptionsDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

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

// Do executes the "youtube.captions.delete" call.
func (c *CaptionsDeleteCall) Do(opts ...googleapi.CallOption) error {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if err != nil {
		return err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return err
	}
	return nil
	// {
	//   "description": "Deletes a resource.",
	//   "flatPath": "youtube/v3/captions",
	//   "httpMethod": "DELETE",
	//   "id": "youtube.captions.delete",
	//   "parameterOrder": [
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "location": "query",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "onBehalfOf": {
	//       "description": "ID of the Google+ Page for the channel that the request is be on behalf of",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "onBehalfOfContentOwner": {
	//       "description": "*Note:* This parameter is intended exclusively for YouTube content partners. The *onBehalfOfContentOwner* parameter indicates that the request's authorization credentials identify a YouTube CMS user who is acting on behalf of the content owner specified in the parameter value. This parameter is intended for YouTube content partners that own and manage many different YouTube channels. It allows content owners to authenticate once and get access to all their video and channel data, without having to provide authentication credentials for each individual channel. The actual CMS account that the user authenticates with must be linked to the specified YouTube content owner.",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "youtube/v3/captions",
	//   "scopes": [
	//     "https://www.googleapis.com/auth/youtube.force-ssl",
	//     "https://www.googleapis.com/auth/youtubepartner"
	//   ]
	// }

}

// method id "youtube.captions.download":

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

// Download: Downloads a caption track.
func (r *CaptionsService) Download(id string) *CaptionsDownloadCall {
	c := &CaptionsDownloadCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.id = id
	return c
}

// OnBehalfOf sets the optional parameter "onBehalfOf": ID of the
// Google+ Page for the channel that the request is be on behalf of
func (c *CaptionsDownloadCall) OnBehalfOf(onBehalfOf string) *CaptionsDownloadCall {
	c.urlParams_.Set("onBehalfOf", onBehalfOf)
	return c
}

// OnBehalfOfContentOwner sets the optional parameter
// "onBehalfOfContentOwner": *Note:* This parameter is intended
// exclusively for YouTube content partners. The
// *onBehalfOfContentOwner* parameter indicates that the request's
// authorization credentials identify a YouTube CMS user who is acting
// on behalf of the content owner specified in the parameter value. This
// parameter is intended for YouTube content partners that own and
// manage many different YouTube channels. It allows content owners to
// authenticate once and get access to all their video and channel data,
// without having to provide authentication credentials for each
// individual channel. The actual CMS account that the user
// authenticates with must be linked to the specified YouTube content
// owner.
func (c *CaptionsDownloadCall) OnBehalfOfContentOwner(onBehalfOfContentOwner string) *CaptionsDownloadCall {
	c.urlParams_.Set("onBehalfOfContentOwner", onBehalfOfContentOwner)
	return c
}

// Tfmt sets the optional parameter "tfmt": Convert the captions into
// this format. Supported options are sbv, srt, and vtt.
func (c *CaptionsDownloadCall) Tfmt(tfmt string) *CaptionsDownloadCall {
	c.urlParams_.Set("tfmt", tfmt)
	return c
}

// Tlang sets the optional parameter "tlang": tlang is the language
// code; machine translate the captions into this language.
func (c *CaptionsDownloadCall) Tlang(tlang string) *CaptionsDownloadCall {
	c.urlParams_.Set("tlang", tlang)
	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 *CaptionsDownloadCall) Fields(s ...googleapi.Field) *CaptionsDownloadCall {
	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 *CaptionsDownloadCall) IfNoneMatch(entityTag string) *CaptionsDownloadCall {
	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 *CaptionsDownloadCall) Context(ctx context.Context) *CaptionsDownloadCall {
	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 *CaptionsDownloadCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *CaptionsDownloadCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200912")
	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, "youtube/v3/captions/{id}")
	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{
		"id": c.id,
	})
	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 *CaptionsDownloadCall) 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 "youtube.captions.download" call.
func (c *CaptionsDownloadCall) Do(opts ...googleapi.CallOption) error {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if err != nil {
		return err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return err
	}
	return nil
	// {
	//   "description": "Downloads a caption track.",
	//   "flatPath": "youtube/v3/captions/{id}",
	//   "httpMethod": "GET",
	//   "id": "youtube.captions.download",
	//   "parameterOrder": [
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "The ID of the caption track to download, required for One Platform.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "onBehalfOf": {
	//       "description": "ID of the Google+ Page for the channel that the request is be on behalf of",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "onBehalfOfContentOwner": {
	//       "description": "*Note:* This parameter is intended exclusively for YouTube content partners. The *onBehalfOfContentOwner* parameter indicates that the request's authorization credentials identify a YouTube CMS user who is acting on behalf of the content owner specified in the parameter value. This parameter is intended for YouTube content partners that own and manage many different YouTube channels. It allows content owners to authenticate once and get access to all their video and channel data, without having to provide authentication credentials for each individual channel. The actual CMS account that the user authenticates with must be linked to the specified YouTube content owner.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "tfmt": {
	//       "description": "Convert the captions into this format. Supported options are sbv, srt, and vtt.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "tlang": {
	//       "description": "tlang is the language code; machine translate the captions into this language.",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "youtube/v3/captions/{id}",
	//   "scopes": [
	//     "https://www.googleapis.com/auth/youtube.force-ssl",
	//     "https://www.googleapis.com/auth/youtubepartner"
	//   ],
	//   "supportsMediaDownload": true,
	//   "useMediaDownloadService": true
	// }

}

// method id "youtube.captions.insert":

type CaptionsInsertCall struct {
	s          *Service
	caption    *Caption
	urlParams_ gensupport.URLParams
	mediaInfo_ *gensupport.MediaInfo
	ctx_       context.Context
	header_    http.Header
}

// Insert: Inserts a new resource into this collection.
func (r *CaptionsService) Insert(part []string, caption *Caption) *CaptionsInsertCall {
	c := &CaptionsInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.urlParams_.SetMulti("part", append([]string{}, part...))
	c.caption = caption
	return c
}

// OnBehalfOf sets the optional parameter "onBehalfOf": ID of the
// Google+ Page for the channel that the request is be on behalf of
func (c *CaptionsInsertCall) OnBehalfOf(onBehalfOf string) *CaptionsInsertCall {
	c.urlParams_.Set("onBehalfOf", onBehalfOf)
	return c
}

// OnBehalfOfContentOwner sets the optional parameter
// "onBehalfOfContentOwner": *Note:* This parameter is intended
// exclusively for YouTube content partners. The
// *onBehalfOfContentOwner* parameter indicates that the request's
// authorization credentials identify a YouTube CMS user who is acting
// on behalf of the content owner specified in the parameter value. This
// parameter is intended for YouTube content partners that own and
// manage many different YouTube channels. It allows content owners to
// authenticate once and get access to all their video and channel data,
// without having to provide authentication credentials for each
// individual channel. The actual CMS account that the user
// authenticates with must be linked to the specified YouTube content
// owner.
func (c *CaptionsInsertCall) OnBehalfOfContentOwner(onBehalfOfContentOwner string) *CaptionsInsertCall {
	c.urlParams_.Set("onBehalfOfContentOwner", onBehalfOfContentOwner)
	return c
}

// Sync sets the optional parameter "sync": Extra parameter to allow
// automatically syncing the uploaded caption/transcript with the audio.
func (c *CaptionsInsertCall) Sync(sync bool) *CaptionsInsertCall {
	c.urlParams_.Set("sync", fmt.Sprint(sync))
	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 *CaptionsInsertCall) Media(r io.Reader, options ...googleapi.MediaOption) *CaptionsInsertCall {
	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 *CaptionsInsertCall) ResumableMedia(ctx context.Context, r io.ReaderAt, size int64, mediaType string) *CaptionsInsertCall {
	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 *CaptionsInsertCall) ProgressUpdater(pu googleapi.ProgressUpdater) *CaptionsInsertCall {
	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 *CaptionsInsertCall) Fields(s ...googleapi.Field) *CaptionsInsertCall {
	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 *CaptionsInsertCall) Context(ctx context.Context) *CaptionsInsertCall {
	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 *CaptionsInsertCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *CaptionsInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200912")
	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.caption)
	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, "youtube/v3/captions")
	if c.mediaInfo_ != nil {
		urls = googleapi.ResolveRelative(c.s.BasePath, "/upload/youtube/v3/captions")
		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
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "youtube.captions.insert" call.
// Exactly one of *Caption or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Caption.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 *CaptionsInsertCall) Do(opts ...googleapi.CallOption) (*Caption, 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 := &Caption{
		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": "Inserts a new resource into this collection.",
	//   "flatPath": "youtube/v3/captions",
	//   "httpMethod": "POST",
	//   "id": "youtube.captions.insert",
	//   "mediaUpload": {
	//     "accept": [
	//       "text/xml",
	//       "application/octet-stream",
	//       "*/*"
	//     ],
	//     "maxSize": "104857600",
	//     "protocols": {
	//       "simple": {
	//         "multipart": true,
	//         "path": "/upload/youtube/v3/captions"
	//       }
	//     }
	//   },
	//   "parameterOrder": [
	//     "part"
	//   ],
	//   "parameters": {
	//     "onBehalfOf": {
	//       "description": "ID of the Google+ Page for the channel that the request is be on behalf of",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "onBehalfOfContentOwner": {
	//       "description": "*Note:* This parameter is intended exclusively for YouTube content partners. The *onBehalfOfContentOwner* parameter indicates that the request's authorization credentials identify a YouTube CMS user who is acting on behalf of the content owner specified in the parameter value. This parameter is intended for YouTube content partners that own and manage many different YouTube channels. It allows content owners to authenticate once and get access to all their video and channel data, without having to provide authentication credentials for each individual channel. The actual CMS account that the user authenticates with must be linked to the specified YouTube content owner.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "part": {
	//       "description": "The *part* parameter specifies the caption resource parts that the API response will include. Set the parameter value to snippet.",
	//       "location": "query",
	//       "repeated": true,
	//       "required": true,
	//       "type": "string"
	//     },
	//     "sync": {
	//       "description": "Extra parameter to allow automatically syncing the uploaded caption/transcript with the audio.",
	//       "location": "query",
	//       "type": "boolean"
	//     }
	//   },
	//   "path": "youtube/v3/captions",
	//   "request": {
	//     "$ref": "Caption"
	//   },
	//   "response": {
	//     "$ref": "Caption"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/youtube.force-ssl",
	//     "https://www.googleapis.com/auth/youtubepartner"
	//   ],
	//   "supportsMediaUpload": true
	// }

}

// method id "youtube.captions.list":

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

// List: Retrieves a list of resources, possibly filtered.
func (r *CaptionsService) List(videoId string, part []string) *CaptionsListCall {
	c := &CaptionsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.urlParams_.Set("videoId", videoId)
	c.urlParams_.SetMulti("part", append([]string{}, part...))
	return c
}

// Id sets the optional parameter "id": Returns the captions with the
// given IDs for Stubby or Apiary.
func (c *CaptionsListCall) Id(id ...string) *CaptionsListCall {
	c.urlParams_.SetMulti("id", append([]string{}, id...))
	return c
}

// OnBehalfOf sets the optional parameter "onBehalfOf": ID of the
// Google+ Page for the channel that the request is on behalf of.
func (c *CaptionsListCall) OnBehalfOf(onBehalfOf string) *CaptionsListCall {
	c.urlParams_.Set("onBehalfOf", onBehalfOf)
	return c
}

// OnBehalfOfContentOwner sets the optional parameter
// "onBehalfOfContentOwner": *Note:* This parameter is intended
// exclusively for YouTube content partners. The
// *onBehalfOfContentOwner* parameter indicates that the request's
// authorization credentials identify a YouTube CMS user who is acting
// on behalf of the content owner specified in the parameter value. This
// parameter is intended for YouTube content partners that own and
// manage many different YouTube channels. It allows content owners to
// authenticate once and get access to all their video and channel data,
// without having to provide authentication credentials for each
// individual channel. The actual CMS account that the user
// authenticates with must be linked to the specified YouTube content
// owner.
func (c *CaptionsListCall) OnBehalfOfContentOwner(onBehalfOfContentOwner string) *CaptionsListCall {
	c.urlParams_.Set("onBehalfOfContentOwner", onBehalfOfContentOwner)
	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 *CaptionsListCall) Fields(s ...googleapi.Field) *CaptionsListCall {
	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 *CaptionsListCall) IfNoneMatch(entityTag string) *CaptionsListCall {
	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 *CaptionsListCall) Context(ctx context.Context) *CaptionsListCall {
	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 *CaptionsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *CaptionsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200912")
	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, "youtube/v3/captions")
	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 "youtube.captions.list" call.
// Exactly one of *CaptionListResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *CaptionListResponse.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 *CaptionsListCall) Do(opts ...googleapi.CallOption) (*CaptionListResponse, 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 := &CaptionListResponse{
		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": "Retrieves a list of resources, possibly filtered.",
	//   "flatPath": "youtube/v3/captions",
	//   "httpMethod": "GET",
	//   "id": "youtube.captions.list",
	//   "parameterOrder": [
	//     "videoId",
	//     "part"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "Returns the captions with the given IDs for Stubby or Apiary.",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "onBehalfOf": {
	//       "description": "ID of the Google+ Page for the channel that the request is on behalf of.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "onBehalfOfContentOwner": {
	//       "description": "*Note:* This parameter is intended exclusively for YouTube content partners. The *onBehalfOfContentOwner* parameter indicates that the request's authorization credentials identify a YouTube CMS user who is acting on behalf of the content owner specified in the parameter value. This parameter is intended for YouTube content partners that own and manage many different YouTube channels. It allows content owners to authenticate once and get access to all their video and channel data, without having to provide authentication credentials for each individual channel. The actual CMS account that the user authenticates with must be linked to the specified YouTube content owner.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "part": {
	//       "description": "The *part* parameter specifies a comma-separated list of one or more caption resource parts that the API response will include. The part names that you can include in the parameter value are id and snippet.",
	//       "location": "query",
	//       "repeated": true,
	//       "required": true,
	//       "type": "string"
	//     },
	//     "videoId": {
	//       "description": "Returns the captions for the specified video.",
	//       "location": "query",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "youtube/v3/captions",
	//   "response": {
	//     "$ref": "CaptionListResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/youtube.force-ssl",
	//     "https://www.googleapis.com/auth/youtubepartner"
	//   ]
	// }

}

// method id "youtube.captions.update":

type CaptionsUpdateCall struct {
	s          *Service
	caption    *Caption
	urlParams_ gensupport.URLParams
	mediaInfo_ *gensupport.MediaInfo
	ctx_       context.Context
	header_    http.Header
}

// Update: Updates an existing resource.
func (r *CaptionsService) Update(part []string, caption *Caption) *CaptionsUpdateCall {
	c := &CaptionsUpdateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.urlParams_.SetMulti("part", append([]string{}, part...))
	c.caption = caption
	return c
}

// OnBehalfOf sets the optional parameter "onBehalfOf": ID of the
// Google+ Page for the channel that the request is on behalf of.
func (c *CaptionsUpdateCall) OnBehalfOf(onBehalfOf string) *CaptionsUpdateCall {
	c.urlParams_.Set("onBehalfOf", onBehalfOf)
	return c
}

// OnBehalfOfContentOwner sets the optional parameter
// "onBehalfOfContentOwner": *Note:* This parameter is intended
// exclusively for YouTube content partners. The
// *onBehalfOfContentOwner* parameter indicates that the request's
// authorization credentials identify a YouTube CMS user who is acting
// on behalf of the content owner specified in the parameter value. This
// parameter is intended for YouTube content partners that own and
// manage many different YouTube channels. It allows content owners to
// authenticate once and get access to all their video and channel data,
// without having to provide authentication credentials for each
// individual channel. The actual CMS account that the user
// authenticates with must be linked to the specified YouTube content
// owner.
func (c *CaptionsUpdateCall) OnBehalfOfContentOwner(onBehalfOfContentOwner string) *CaptionsUpdateCall {
	c.urlParams_.Set("onBehalfOfContentOwner", onBehalfOfContentOwner)
	return c
}

// Sync sets the optional parameter "sync": Extra parameter to allow
// automatically syncing the uploaded caption/transcript with the audio.
func (c *CaptionsUpdateCall) Sync(sync bool) *CaptionsUpdateCall {
	c.urlParams_.Set("sync", fmt.Sprint(sync))
	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 *CaptionsUpdateCall) Media(r io.Reader, options ...googleapi.MediaOption) *CaptionsUpdateCall {
	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 *CaptionsUpdateCall) ResumableMedia(ctx context.Context, r io.ReaderAt, size int64, mediaType string) *CaptionsUpdateCall {
	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 *CaptionsUpdateCall) ProgressUpdater(pu googleapi.ProgressUpdater) *CaptionsUpdateCall {
	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 *CaptionsUpdateCall) Fields(s ...googleapi.Field) *CaptionsUpdateCall {
	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 *CaptionsUpdateCall) Context(ctx context.Context) *CaptionsUpdateCall {
	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 *CaptionsUpdateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *CaptionsUpdateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200912")
	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.caption)
	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, "youtube/v3/captions")
	if c.mediaInfo_ != nil {
		urls = googleapi.ResolveRelative(c.s.BasePath, "/upload/youtube/v3/captions")
		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("PUT", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	req.GetBody = getBody
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "youtube.captions.update" call.
// Exactly one of *Caption or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Caption.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 *CaptionsUpdateCall) Do(opts ...googleapi.CallOption) (*Caption, 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 := &Caption{
		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 existing resource.",
	//   "flatPath": "youtube/v3/captions",
	//   "httpMethod": "PUT",
	//   "id": "youtube.captions.update",
	//   "mediaUpload": {
	//     "accept": [
	//       "text/xml",
	//       "application/octet-stream",
	//       "*/*"
	//     ],
	//     "maxSize": "104857600",
	//     "protocols": {
	//       "simple": {
	//         "multipart": true,
	//         "path": "/upload/youtube/v3/captions"
	//       }
	//     }
	//   },
	//   "parameterOrder": [
	//     "part"
	//   ],
	//   "parameters": {
	//     "onBehalfOf": {
	//       "description": "ID of the Google+ Page for the channel that the request is on behalf of.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "onBehalfOfContentOwner": {
	//       "description": "*Note:* This parameter is intended exclusively for YouTube content partners. The *onBehalfOfContentOwner* parameter indicates that the request's authorization credentials identify a YouTube CMS user who is acting on behalf of the content owner specified in the parameter value. This parameter is intended for YouTube content partners that own and manage many different YouTube channels. It allows content owners to authenticate once and get access to all their video and channel data, without having to provide authentication credentials for each individual channel. The actual CMS account that the user authenticates with must be linked to the specified YouTube content owner.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "part": {
	//       "description": "The *part* parameter specifies a comma-separated list of one or more caption resource parts that the API response will include. The part names that you can include in the parameter value are id and snippet.",
	//       "location": "query",
	//       "repeated": true,
	//       "required": true,
	//       "type": "string"
	//     },
	//     "sync": {
	//       "description": "Extra parameter to allow automatically syncing the uploaded caption/transcript with the audio.",
	//       "location": "query",
	//       "type": "boolean"
	//     }
	//   },
	//   "path": "youtube/v3/captions",
	//   "request": {
	//     "$ref": "Caption"
	//   },
	//   "response": {
	//     "$ref": "Caption"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/youtube.force-ssl",
	//     "https://www.googleapis.com/auth/youtubepartner"
	//   ],
	//   "supportsMediaUpload": true
	// }

}

// method id "youtube.channelBanners.insert":

type ChannelBannersInsertCall struct {
	s                     *Service
	channelbannerresource *ChannelBannerResource
	urlParams_            gensupport.URLParams
	mediaInfo_            *gensupport.MediaInfo
	ctx_                  context.Context
	header_               http.Header
}

// Insert: Inserts a new resource into this collection.
func (r *ChannelBannersService) Insert(channelbannerresource *ChannelBannerResource) *ChannelBannersInsertCall {
	c := &ChannelBannersInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.channelbannerresource = channelbannerresource
	return c
}

// ChannelId sets the optional parameter "channelId": Unused, channel_id
// is currently derived from the security context of the requestor.
func (c *ChannelBannersInsertCall) ChannelId(channelId string) *ChannelBannersInsertCall {
	c.urlParams_.Set("channelId", channelId)
	return c
}

// OnBehalfOfContentOwner sets the optional parameter
// "onBehalfOfContentOwner": *Note:* This parameter is intended
// exclusively for YouTube content partners. The
// *onBehalfOfContentOwner* parameter indicates that the request's
// authorization credentials identify a YouTube CMS user who is acting
// on behalf of the content owner specified in the parameter value. This
// parameter is intended for YouTube content partners that own and
// manage many different YouTube channels. It allows content owners to
// authenticate once and get access to all their video and channel data,
// without having to provide authentication credentials for each
// individual channel. The actual CMS account that the user
// authenticates with must be linked to the specified YouTube content
// owner.
func (c *ChannelBannersInsertCall) OnBehalfOfContentOwner(onBehalfOfContentOwner string) *ChannelBannersInsertCall {
	c.urlParams_.Set("onBehalfOfContentOwner", onBehalfOfContentOwner)
	return c
}

// OnBehalfOfContentOwnerChannel sets the optional parameter
// "onBehalfOfContentOwnerChannel": This parameter can only be used in a
// properly authorized request. *Note:* This parameter is intended
// exclusively for YouTube content partners. The
// *onBehalfOfContentOwnerChannel* parameter specifies the YouTube
// channel ID of the channel to which a video is being added. This
// parameter is required when a request specifies a value for the
// onBehalfOfContentOwner parameter, and it can only be used in
// conjunction with that parameter. In addition, the request must be
// authorized using a CMS account that is linked to the content owner
// that the onBehalfOfContentOwner parameter specifies. Finally, the
// channel that the onBehalfOfContentOwnerChannel parameter value
// specifies must be linked to the content owner that the
// onBehalfOfContentOwner parameter specifies. This parameter is
// intended for YouTube content partners that own and manage many
// different YouTube channels. It allows content owners to authenticate
// once and perform actions on behalf of the channel specified in the
// parameter value, without having to provide authentication credentials
// for each separate channel.
func (c *ChannelBannersInsertCall) OnBehalfOfContentOwnerChannel(onBehalfOfContentOwnerChannel string) *ChannelBannersInsertCall {
	c.urlParams_.Set("onBehalfOfContentOwnerChannel", onBehalfOfContentOwnerChannel)
	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 *ChannelBannersInsertCall) Media(r io.Reader, options ...googleapi.MediaOption) *ChannelBannersInsertCall {
	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 *ChannelBannersInsertCall) ResumableMedia(ctx context.Context, r io.ReaderAt, size int64, mediaType string) *ChannelBannersInsertCall {
	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 *ChannelBannersInsertCall) ProgressUpdater(pu googleapi.ProgressUpdater) *ChannelBannersInsertCall {
	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 *ChannelBannersInsertCall) Fields(s ...googleapi.Field) *ChannelBannersInsertCall {
	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 *ChannelBannersInsertCall) Context(ctx context.Context) *ChannelBannersInsertCall {
	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 *ChannelBannersInsertCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ChannelBannersInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200912")
	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.channelbannerresource)
	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, "youtube/v3/channelBanners/insert")
	if c.mediaInfo_ != nil {
		urls = googleapi.ResolveRelative(c.s.BasePath, "/upload/youtube/v3/channelBanners/insert")
		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
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "youtube.channelBanners.insert" call.
// Exactly one of *ChannelBannerResource or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *ChannelBannerResource.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 *ChannelBannersInsertCall) Do(opts ...googleapi.CallOption) (*ChannelBannerResource, 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 := &ChannelBannerResource{
		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": "Inserts a new resource into this collection.",
	//   "flatPath": "youtube/v3/channelBanners/insert",
	//   "httpMethod": "POST",
	//   "id": "youtube.channelBanners.insert",
	//   "mediaUpload": {
	//     "accept": [
	//       "image/jpeg",
	//       "image/png",
	//       "application/octet-stream"
	//     ],
	//     "maxSize": "6291456",
	//     "protocols": {
	//       "simple": {
	//         "multipart": true,
	//         "path": "/upload/youtube/v3/channelBanners/insert"
	//       }
	//     }
	//   },
	//   "parameterOrder": [],
	//   "parameters": {
	//     "channelId": {
	//       "description": "Unused, channel_id is currently derived from the security context of the requestor.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "onBehalfOfContentOwner": {
	//       "description": "*Note:* This parameter is intended exclusively for YouTube content partners. The *onBehalfOfContentOwner* parameter indicates that the request's authorization credentials identify a YouTube CMS user who is acting on behalf of the content owner specified in the parameter value. This parameter is intended for YouTube content partners that own and manage many different YouTube channels. It allows content owners to authenticate once and get access to all their video and channel data, without having to provide authentication credentials for each individual channel. The actual CMS account that the user authenticates with must be linked to the specified YouTube content owner.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "onBehalfOfContentOwnerChannel": {
	//       "description": "This parameter can only be used in a properly authorized request. *Note:* This parameter is intended exclusively for YouTube content partners. The *onBehalfOfContentOwnerChannel* parameter specifies the YouTube channel ID of the channel to which a video is being added. This parameter is required when a request specifies a value for the onBehalfOfContentOwner parameter, and it can only be used in conjunction with that parameter. In addition, the request must be authorized using a CMS account that is linked to the content owner that the onBehalfOfContentOwner parameter specifies. Finally, the channel that the onBehalfOfContentOwnerChannel parameter value specifies must be linked to the content owner that the onBehalfOfContentOwner parameter specifies. This parameter is intended for YouTube content partners that own and manage many different YouTube channels. It allows content owners to authenticate once and perform actions on behalf of the channel specified in the parameter value, without having to provide authentication credentials for each separate channel.",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "youtube/v3/channelBanners/insert",
	//   "request": {
	//     "$ref": "ChannelBannerResource"
	//   },
	//   "response": {
	//     "$ref": "ChannelBannerResource"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/youtube",
	//     "https://www.googleapis.com/auth/youtube.force-ssl",
	//     "https://www.googleapis.com/auth/youtube.upload"
	//   ],
	//   "supportsMediaUpload": true
	// }

}

// method id "youtube.channelSections.delete":

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

// Delete: Deletes a resource.
func (r *ChannelSectionsService) Delete(id string) *ChannelSectionsDeleteCall {
	c := &ChannelSectionsDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.urlParams_.Set("id", id)
	return c
}

// OnBehalfOfContentOwner sets the optional parameter
// "onBehalfOfContentOwner": *Note:* This parameter is intended
// exclusively for YouTube content partners. The
// *onBehalfOfContentOwner* parameter indicates that the request's
// authorization credentials identify a YouTube CMS user who is acting
// on behalf of the content owner specified in the parameter value. This
// parameter is intended for YouTube content partners that own and
// manage many different YouTube channels. It allows content owners to
// authenticate once and get access to all their video and channel data,
// without having to provide authentication credentials for each
// individual channel. The CMS account that the user authenticates with
// must be linked to the specified YouTube content owner.
func (c *ChannelSectionsDeleteCall) OnBehalfOfContentOwner(onBehalfOfContentOwner string) *ChannelSectionsDeleteCall {
	c.urlParams_.Set("onBehalfOfContentOwner", onBehalfOfContentOwner)
	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 *ChannelSectionsDeleteCall) Fields(s ...googleapi.Field) *ChannelSectionsDeleteCall {
	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 *ChannelSectionsDeleteCall) Context(ctx context.Context) *ChannelSectionsDeleteCall {
	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 *ChannelSectionsDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

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

// Do executes the "youtube.channelSections.delete" call.
func (c *ChannelSectionsDeleteCall) Do(opts ...googleapi.CallOption) error {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if err != nil {
		return err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return err
	}
	return nil
	// {
	//   "description": "Deletes a resource.",
	//   "flatPath": "youtube/v3/channelSections",
	//   "httpMethod": "DELETE",
	//   "id": "youtube.channelSections.delete",
	//   "parameterOrder": [
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "location": "query",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "onBehalfOfContentOwner": {
	//       "description": "*Note:* This parameter is intended exclusively for YouTube content partners. The *onBehalfOfContentOwner* parameter indicates that the request's authorization credentials identify a YouTube CMS user who is acting on behalf of the content owner specified in the parameter value. This parameter is intended for YouTube content partners that own and manage many different YouTube channels. It allows content owners to authenticate once and get access to all their video and channel data, without having to provide authentication credentials for each individual channel. The CMS account that the user authenticates with must be linked to the specified YouTube content owner.",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "youtube/v3/channelSections",
	//   "scopes": [
	//     "https://www.googleapis.com/auth/youtube",
	//     "https://www.googleapis.com/auth/youtube.force-ssl",
	//     "https://www.googleapis.com/auth/youtubepartner"
	//   ]
	// }

}

// method id "youtube.channelSections.insert":

type ChannelSectionsInsertCall struct {
	s              *Service
	channelsection *ChannelSection
	urlParams_     gensupport.URLParams
	ctx_           context.Context
	header_        http.Header
}

// Insert: Inserts a new resource into this collection.
func (r *ChannelSectionsService) Insert(part []string, channelsection *ChannelSection) *ChannelSectionsInsertCall {
	c := &ChannelSectionsInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.urlParams_.SetMulti("part", append([]string{}, part...))
	c.channelsection = channelsection
	return c
}

// OnBehalfOfContentOwner sets the optional parameter
// "onBehalfOfContentOwner": *Note:* This parameter is intended
// exclusively for YouTube content partners. The
// *onBehalfOfContentOwner* parameter indicates that the request's
// authorization credentials identify a YouTube CMS user who is acting
// on behalf of the content owner specified in the parameter value. This
// parameter is intended for YouTube content partners that own and
// manage many different YouTube channels. It allows content owners to
// authenticate once and get access to all their video and channel data,
// without having to provide authentication credentials for each
// individual channel. The CMS account that the user authenticates with
// must be linked to the specified YouTube content owner.
func (c *ChannelSectionsInsertCall) OnBehalfOfContentOwner(onBehalfOfContentOwner string) *ChannelSectionsInsertCall {
	c.urlParams_.Set("onBehalfOfContentOwner", onBehalfOfContentOwner)
	return c
}

// OnBehalfOfContentOwnerChannel sets the optional parameter
// "onBehalfOfContentOwnerChannel": This parameter can only be used in a
// properly authorized request. *Note:* This parameter is intended
// exclusively for YouTube content partners. The
// *onBehalfOfContentOwnerChannel* parameter specifies the YouTube
// channel ID of the channel to which a video is being added. This
// parameter is required when a request specifies a value for the
// onBehalfOfContentOwner parameter, and it can only be used in
// conjunction with that parameter. In addition, the request must be
// authorized using a CMS account that is linked to the content owner
// that the onBehalfOfContentOwner parameter specifies. Finally, the
// channel that the onBehalfOfContentOwnerChannel parameter value
// specifies must be linked to the content owner that the
// onBehalfOfContentOwner parameter specifies. This parameter is
// intended for YouTube content partners that own and manage many
// different YouTube channels. It allows content owners to authenticate
// once and perform actions on behalf of the channel specified in the
// parameter value, without having to provide authentication credentials
// for each separate channel.
func (c *ChannelSectionsInsertCall) OnBehalfOfContentOwnerChannel(onBehalfOfContentOwnerChannel string) *ChannelSectionsInsertCall {
	c.urlParams_.Set("onBehalfOfContentOwnerChannel", onBehalfOfContentOwnerChannel)
	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 *ChannelSectionsInsertCall) Fields(s ...googleapi.Field) *ChannelSectionsInsertCall {
	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 *ChannelSectionsInsertCall) Context(ctx context.Context) *ChannelSectionsInsertCall {
	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 *ChannelSectionsInsertCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ChannelSectionsInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200912")
	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.channelsection)
	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, "youtube/v3/channelSections")
	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 "youtube.channelSections.insert" call.
// Exactly one of *ChannelSection or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *ChannelSection.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 *ChannelSectionsInsertCall) Do(opts ...googleapi.CallOption) (*ChannelSection, 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 := &ChannelSection{
		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": "Inserts a new resource into this collection.",
	//   "flatPath": "youtube/v3/channelSections",
	//   "httpMethod": "POST",
	//   "id": "youtube.channelSections.insert",
	//   "parameterOrder": [
	//     "part"
	//   ],
	//   "parameters": {
	//     "onBehalfOfContentOwner": {
	//       "description": "*Note:* This parameter is intended exclusively for YouTube content partners. The *onBehalfOfContentOwner* parameter indicates that the request's authorization credentials identify a YouTube CMS user who is acting on behalf of the content owner specified in the parameter value. This parameter is intended for YouTube content partners that own and manage many different YouTube channels. It allows content owners to authenticate once and get access to all their video and channel data, without having to provide authentication credentials for each individual channel. The CMS account that the user authenticates with must be linked to the specified YouTube content owner.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "onBehalfOfContentOwnerChannel": {
	//       "description": "This parameter can only be used in a properly authorized request. *Note:* This parameter is intended exclusively for YouTube content partners. The *onBehalfOfContentOwnerChannel* parameter specifies the YouTube channel ID of the channel to which a video is being added. This parameter is required when a request specifies a value for the onBehalfOfContentOwner parameter, and it can only be used in conjunction with that parameter. In addition, the request must be authorized using a CMS account that is linked to the content owner that the onBehalfOfContentOwner parameter specifies. Finally, the channel that the onBehalfOfContentOwnerChannel parameter value specifies must be linked to the content owner that the onBehalfOfContentOwner parameter specifies. This parameter is intended for YouTube content partners that own and manage many different YouTube channels. It allows content owners to authenticate once and perform actions on behalf of the channel specified in the parameter value, without having to provide authentication credentials for each separate channel.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "part": {
	//       "description": "The *part* parameter serves two purposes in this operation. It identifies the properties that the write operation will set as well as the properties that the API response will include. The part names that you can include in the parameter value are snippet and contentDetails.",
	//       "location": "query",
	//       "repeated": true,
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "youtube/v3/channelSections",
	//   "request": {
	//     "$ref": "ChannelSection"
	//   },
	//   "response": {
	//     "$ref": "ChannelSection"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/youtube",
	//     "https://www.googleapis.com/auth/youtube.force-ssl",
	//     "https://www.googleapis.com/auth/youtubepartner"
	//   ]
	// }

}

// method id "youtube.channelSections.list":

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

// List: Retrieves a list of resources, possibly filtered.
func (r *ChannelSectionsService) List(part []string) *ChannelSectionsListCall {
	c := &ChannelSectionsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.urlParams_.SetMulti("part", append([]string{}, part...))
	return c
}

// ChannelId sets the optional parameter "channelId": Return the
// ChannelSections owned by the specified channel ID.
func (c *ChannelSectionsListCall) ChannelId(channelId string) *ChannelSectionsListCall {
	c.urlParams_.Set("channelId", channelId)
	return c
}

// Hl sets the optional parameter "hl": Return content in specified
// language
func (c *ChannelSectionsListCall) Hl(hl string) *ChannelSectionsListCall {
	c.urlParams_.Set("hl", hl)
	return c
}

// Id sets the optional parameter "id": Return the ChannelSections with
// the given IDs for Stubby or Apiary.
func (c *ChannelSectionsListCall) Id(id ...string) *ChannelSectionsListCall {
	c.urlParams_.SetMulti("id", append([]string{}, id...))
	return c
}

// Mine sets the optional parameter "mine": Return the ChannelSections
// owned by the authenticated user.
func (c *ChannelSectionsListCall) Mine(mine bool) *ChannelSectionsListCall {
	c.urlParams_.Set("mine", fmt.Sprint(mine))
	return c
}

// OnBehalfOfContentOwner sets the optional parameter
// "onBehalfOfContentOwner": *Note:* This parameter is intended
// exclusively for YouTube content partners. The
// *onBehalfOfContentOwner* parameter indicates that the request's
// authorization credentials identify a YouTube CMS user who is acting
// on behalf of the content owner specified in the parameter value. This
// parameter is intended for YouTube content partners that own and
// manage many different YouTube channels. It allows content owners to
// authenticate once and get access to all their video and channel data,
// without having to provide authentication credentials for each
// individual channel. The CMS account that the user authenticates with
// must be linked to the specified YouTube content owner.
func (c *ChannelSectionsListCall) OnBehalfOfContentOwner(onBehalfOfContentOwner string) *ChannelSectionsListCall {
	c.urlParams_.Set("onBehalfOfContentOwner", onBehalfOfContentOwner)
	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 *ChannelSectionsListCall) Fields(s ...googleapi.Field) *ChannelSectionsListCall {
	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 *ChannelSectionsListCall) IfNoneMatch(entityTag string) *ChannelSectionsListCall {
	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 *ChannelSectionsListCall) Context(ctx context.Context) *ChannelSectionsListCall {
	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 *ChannelSectionsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ChannelSectionsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200912")
	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, "youtube/v3/channelSections")
	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 "youtube.channelSections.list" call.
// Exactly one of *ChannelSectionListResponse or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *ChannelSectionListResponse.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 *ChannelSectionsListCall) Do(opts ...googleapi.CallOption) (*ChannelSectionListResponse, 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 := &ChannelSectionListResponse{
		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": "Retrieves a list of resources, possibly filtered.",
	//   "flatPath": "youtube/v3/channelSections",
	//   "httpMethod": "GET",
	//   "id": "youtube.channelSections.list",
	//   "parameterOrder": [
	//     "part"
	//   ],
	//   "parameters": {
	//     "channelId": {
	//       "description": "Return the ChannelSections owned by the specified channel ID.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "hl": {
	//       "description": "Return content in specified language",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "id": {
	//       "description": "Return the ChannelSections with the given IDs for Stubby or Apiary.",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "mine": {
	//       "description": "Return the ChannelSections owned by the authenticated user.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "onBehalfOfContentOwner": {
	//       "description": "*Note:* This parameter is intended exclusively for YouTube content partners. The *onBehalfOfContentOwner* parameter indicates that the request's authorization credentials identify a YouTube CMS user who is acting on behalf of the content owner specified in the parameter value. This parameter is intended for YouTube content partners that own and manage many different YouTube channels. It allows content owners to authenticate once and get access to all their video and channel data, without having to provide authentication credentials for each individual channel. The CMS account that the user authenticates with must be linked to the specified YouTube content owner.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "part": {
	//       "description": "The *part* parameter specifies a comma-separated list of one or more channelSection resource properties that the API response will include. The part names that you can include in the parameter value are id, snippet, and contentDetails. If the parameter identifies a property that contains child properties, the child properties will be included in the response. For example, in a channelSection resource, the snippet property contains other properties, such as a display title for the channelSection. If you set *part=snippet*, the API response will also contain all of those nested properties.",
	//       "location": "query",
	//       "repeated": true,
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "youtube/v3/channelSections",
	//   "response": {
	//     "$ref": "ChannelSectionListResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/youtube",
	//     "https://www.googleapis.com/auth/youtube.force-ssl",
	//     "https://www.googleapis.com/auth/youtube.readonly",
	//     "https://www.googleapis.com/auth/youtubepartner"
	//   ]
	// }

}

// method id "youtube.channelSections.update":

type ChannelSectionsUpdateCall struct {
	s              *Service
	channelsection *ChannelSection
	urlParams_     gensupport.URLParams
	ctx_           context.Context
	header_        http.Header
}

// Update: Updates an existing resource.
func (r *ChannelSectionsService) Update(part []string, channelsection *ChannelSection) *ChannelSectionsUpdateCall {
	c := &ChannelSectionsUpdateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.urlParams_.SetMulti("part", append([]string{}, part...))
	c.channelsection = channelsection
	return c
}

// OnBehalfOfContentOwner sets the optional parameter
// "onBehalfOfContentOwner": *Note:* This parameter is intended
// exclusively for YouTube content partners. The
// *onBehalfOfContentOwner* parameter indicates that the request's
// authorization credentials identify a YouTube CMS user who is acting
// on behalf of the content owner specified in the parameter value. This
// parameter is intended for YouTube content partners that own and
// manage many different YouTube channels. It allows content owners to
// authenticate once and get access to all their video and channel data,
// without having to provide authentication credentials for each
// individual channel. The CMS account that the user authenticates with
// must be linked to the specified YouTube content owner.
func (c *ChannelSectionsUpdateCall) OnBehalfOfContentOwner(onBehalfOfContentOwner string) *ChannelSectionsUpdateCall {
	c.urlParams_.Set("onBehalfOfContentOwner", onBehalfOfContentOwner)
	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 *ChannelSectionsUpdateCall) Fields(s ...googleapi.Field) *ChannelSectionsUpdateCall {
	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 *ChannelSectionsUpdateCall) Context(ctx context.Context) *ChannelSectionsUpdateCall {
	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 *ChannelSectionsUpdateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

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

// Do executes the "youtube.channelSections.update" call.
// Exactly one of *ChannelSection or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *ChannelSection.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 *ChannelSectionsUpdateCall) Do(opts ...googleapi.CallOption) (*ChannelSection, 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 := &ChannelSection{
		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 existing resource.",
	//   "flatPath": "youtube/v3/channelSections",
	//   "httpMethod": "PUT",
	//   "id": "youtube.channelSections.update",
	//   "parameterOrder": [
	//     "part"
	//   ],
	//   "parameters": {
	//     "onBehalfOfContentOwner": {
	//       "description": "*Note:* This parameter is intended exclusively for YouTube content partners. The *onBehalfOfContentOwner* parameter indicates that the request's authorization credentials identify a YouTube CMS user who is acting on behalf of the content owner specified in the parameter value. This parameter is intended for YouTube content partners that own and manage many different YouTube channels. It allows content owners to authenticate once and get access to all their video and channel data, without having to provide authentication credentials for each individual channel. The CMS account that the user authenticates with must be linked to the specified YouTube content owner.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "part": {
	//       "description": "The *part* parameter serves two purposes in this operation. It identifies the properties that the write operation will set as well as the properties that the API response will include. The part names that you can include in the parameter value are snippet and contentDetails.",
	//       "location": "query",
	//       "repeated": true,
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "youtube/v3/channelSections",
	//   "request": {
	//     "$ref": "ChannelSection"
	//   },
	//   "response": {
	//     "$ref": "ChannelSection"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/youtube",
	//     "https://www.googleapis.com/auth/youtube.force-ssl",
	//     "https://www.googleapis.com/auth/youtubepartner"
	//   ]
	// }

}

// method id "youtube.channels.list":

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

// List: Retrieves a list of resources, possibly filtered.
func (r *ChannelsService) List(part []string) *ChannelsListCall {
	c := &ChannelsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.urlParams_.SetMulti("part", append([]string{}, part...))
	return c
}

// CategoryId sets the optional parameter "categoryId": Return the
// channels within the specified guide category ID.
func (c *ChannelsListCall) CategoryId(categoryId string) *ChannelsListCall {
	c.urlParams_.Set("categoryId", categoryId)
	return c
}

// ForUsername sets the optional parameter "forUsername": Return the
// channel associated with a YouTube username.
func (c *ChannelsListCall) ForUsername(forUsername string) *ChannelsListCall {
	c.urlParams_.Set("forUsername", forUsername)
	return c
}

// Hl sets the optional parameter "hl": Stands for "host language".
// Specifies the localization language of the metadata to be filled into
// snippet.localized. The field is filled with the default metadata if
// there is no localization in the specified language. The parameter
// value must be a language code included in the list returned by the
// i18nLanguages.list method (e.g. en_US, es_MX).
func (c *ChannelsListCall) Hl(hl string) *ChannelsListCall {
	c.urlParams_.Set("hl", hl)
	return c
}

// Id sets the optional parameter "id": Return the channels with the
// specified IDs.
func (c *ChannelsListCall) Id(id ...string) *ChannelsListCall {
	c.urlParams_.SetMulti("id", append([]string{}, id...))
	return c
}

// ManagedByMe sets the optional parameter "managedByMe": Return the
// channels managed by the authenticated user.
func (c *ChannelsListCall) ManagedByMe(managedByMe bool) *ChannelsListCall {
	c.urlParams_.Set("managedByMe", fmt.Sprint(managedByMe))
	return c
}

// MaxResults sets the optional parameter "maxResults": The *maxResults*
// parameter specifies the maximum number of items that should be
// returned in the result set.
func (c *ChannelsListCall) MaxResults(maxResults int64) *ChannelsListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// Mine sets the optional parameter "mine": Return the ids of channels
// owned by the authenticated user.
func (c *ChannelsListCall) Mine(mine bool) *ChannelsListCall {
	c.urlParams_.Set("mine", fmt.Sprint(mine))
	return c
}

// MySubscribers sets the optional parameter "mySubscribers": Return the
// channels subscribed to the authenticated user
func (c *ChannelsListCall) MySubscribers(mySubscribers bool) *ChannelsListCall {
	c.urlParams_.Set("mySubscribers", fmt.Sprint(mySubscribers))
	return c
}

// OnBehalfOfContentOwner sets the optional parameter
// "onBehalfOfContentOwner": *Note:* This parameter is intended
// exclusively for YouTube content partners. The
// *onBehalfOfContentOwner* parameter indicates that the request's
// authorization credentials identify a YouTube CMS user who is acting
// on behalf of the content owner specified in the parameter value. This
// parameter is intended for YouTube content partners that own and
// manage many different YouTube channels. It allows content owners to
// authenticate once and get access to all their video and channel data,
// without having to provide authentication credentials for each
// individual channel. The CMS account that the user authenticates with
// must be linked to the specified YouTube content owner.
func (c *ChannelsListCall) OnBehalfOfContentOwner(onBehalfOfContentOwner string) *ChannelsListCall {
	c.urlParams_.Set("onBehalfOfContentOwner", onBehalfOfContentOwner)
	return c
}

// PageToken sets the optional parameter "pageToken": The *pageToken*
// parameter identifies a specific page in the result set that should be
// returned. In an API response, the nextPageToken and prevPageToken
// properties identify other pages that could be retrieved.
func (c *ChannelsListCall) PageToken(pageToken string) *ChannelsListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

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

func (c *ChannelsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200912")
	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, "youtube/v3/channels")
	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 "youtube.channels.list" call.
// Exactly one of *ChannelListResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *ChannelListResponse.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 *ChannelsListCall) Do(opts ...googleapi.CallOption) (*ChannelListResponse, 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 := &ChannelListResponse{
		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": "Retrieves a list of resources, possibly filtered.",
	//   "flatPath": "youtube/v3/channels",
	//   "httpMethod": "GET",
	//   "id": "youtube.channels.list",
	//   "parameterOrder": [
	//     "part"
	//   ],
	//   "parameters": {
	//     "categoryId": {
	//       "description": "Return the channels within the specified guide category ID.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "forUsername": {
	//       "description": "Return the channel associated with a YouTube username.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "hl": {
	//       "description": "Stands for \"host language\". Specifies the localization language of the metadata to be filled into snippet.localized. The field is filled with the default metadata if there is no localization in the specified language. The parameter value must be a language code included in the list returned by the i18nLanguages.list method (e.g. en_US, es_MX).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "id": {
	//       "description": "Return the channels with the specified IDs.",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "managedByMe": {
	//       "description": "Return the channels managed by the authenticated user.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "maxResults": {
	//       "default": "5",
	//       "description": "The *maxResults* parameter specifies the maximum number of items that should be returned in the result set.",
	//       "format": "uint32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "mine": {
	//       "description": "Return the ids of channels owned by the authenticated user.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "mySubscribers": {
	//       "description": "Return the channels subscribed to the authenticated user",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "onBehalfOfContentOwner": {
	//       "description": "*Note:* This parameter is intended exclusively for YouTube content partners. The *onBehalfOfContentOwner* parameter indicates that the request's authorization credentials identify a YouTube CMS user who is acting on behalf of the content owner specified in the parameter value. This parameter is intended for YouTube content partners that own and manage many different YouTube channels. It allows content owners to authenticate once and get access to all their video and channel data, without having to provide authentication credentials for each individual channel. The CMS account that the user authenticates with must be linked to the specified YouTube content owner.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageToken": {
	//       "description": "The *pageToken* parameter identifies a specific page in the result set that should be returned. In an API response, the nextPageToken and prevPageToken properties identify other pages that could be retrieved.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "part": {
	//       "description": "The *part* parameter specifies a comma-separated list of one or more channel resource properties that the API response will include. If the parameter identifies a property that contains child properties, the child properties will be included in the response. For example, in a channel resource, the contentDetails property contains other properties, such as the uploads properties. As such, if you set *part=contentDetails*, the API response will also contain all of those nested properties.",
	//       "location": "query",
	//       "repeated": true,
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "youtube/v3/channels",
	//   "response": {
	//     "$ref": "ChannelListResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/youtube",
	//     "https://www.googleapis.com/auth/youtube.force-ssl",
	//     "https://www.googleapis.com/auth/youtube.readonly",
	//     "https://www.googleapis.com/auth/youtubepartner",
	//     "https://www.googleapis.com/auth/youtubepartner-channel-audit"
	//   ]
	// }

}

// 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 *ChannelsListCall) Pages(ctx context.Context, f func(*ChannelListResponse) 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 "youtube.channels.update":

type ChannelsUpdateCall struct {
	s          *Service
	channel    *Channel
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Update: Updates an existing resource.
func (r *ChannelsService) Update(part []string, channel *Channel) *ChannelsUpdateCall {
	c := &ChannelsUpdateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.urlParams_.SetMulti("part", append([]string{}, part...))
	c.channel = channel
	return c
}

// OnBehalfOfContentOwner sets the optional parameter
// "onBehalfOfContentOwner": The *onBehalfOfContentOwner* parameter
// indicates that the authenticated user is acting on behalf of the
// content owner specified in the parameter value. This parameter is
// intended for YouTube content partners that own and manage many
// different YouTube channels. It allows content owners to authenticate
// once and get access to all their video and channel data, without
// having to provide authentication credentials for each individual
// channel. The actual CMS account that the user authenticates with
// needs to be linked to the specified YouTube content owner.
func (c *ChannelsUpdateCall) OnBehalfOfContentOwner(onBehalfOfContentOwner string) *ChannelsUpdateCall {
	c.urlParams_.Set("onBehalfOfContentOwner", onBehalfOfContentOwner)
	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 *ChannelsUpdateCall) Fields(s ...googleapi.Field) *ChannelsUpdateCall {
	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 *ChannelsUpdateCall) Context(ctx context.Context) *ChannelsUpdateCall {
	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 *ChannelsUpdateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

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

// Do executes the "youtube.channels.update" call.
// Exactly one of *Channel or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Channel.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 *ChannelsUpdateCall) Do(opts ...googleapi.CallOption) (*Channel, 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 := &Channel{
		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 existing resource.",
	//   "flatPath": "youtube/v3/channels",
	//   "httpMethod": "PUT",
	//   "id": "youtube.channels.update",
	//   "parameterOrder": [
	//     "part"
	//   ],
	//   "parameters": {
	//     "onBehalfOfContentOwner": {
	//       "description": "The *onBehalfOfContentOwner* parameter indicates that the authenticated user is acting on behalf of the content owner specified in the parameter value. This parameter is intended for YouTube content partners that own and manage many different YouTube channels. It allows content owners to authenticate once and get access to all their video and channel data, without having to provide authentication credentials for each individual channel. The actual CMS account that the user authenticates with needs to be linked to the specified YouTube content owner.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "part": {
	//       "description": "The *part* parameter serves two purposes in this operation. It identifies the properties that the write operation will set as well as the properties that the API response will include. The API currently only allows the parameter value to be set to either brandingSettings or invideoPromotion. (You cannot update both of those parts with a single request.) Note that this method overrides the existing values for all of the mutable properties that are contained in any parts that the parameter value specifies.",
	//       "location": "query",
	//       "repeated": true,
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "youtube/v3/channels",
	//   "request": {
	//     "$ref": "Channel"
	//   },
	//   "response": {
	//     "$ref": "Channel"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/youtube",
	//     "https://www.googleapis.com/auth/youtube.force-ssl",
	//     "https://www.googleapis.com/auth/youtubepartner"
	//   ]
	// }

}

// method id "youtube.commentThreads.insert":

type CommentThreadsInsertCall struct {
	s             *Service
	commentthread *CommentThread
	urlParams_    gensupport.URLParams
	ctx_          context.Context
	header_       http.Header
}

// Insert: Inserts a new resource into this collection.
func (r *CommentThreadsService) Insert(part []string, commentthread *CommentThread) *CommentThreadsInsertCall {
	c := &CommentThreadsInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.urlParams_.SetMulti("part", append([]string{}, part...))
	c.commentthread = commentthread
	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 *CommentThreadsInsertCall) Fields(s ...googleapi.Field) *CommentThreadsInsertCall {
	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 *CommentThreadsInsertCall) Context(ctx context.Context) *CommentThreadsInsertCall {
	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 *CommentThreadsInsertCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *CommentThreadsInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200912")
	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.commentthread)
	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, "youtube/v3/commentThreads")
	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 "youtube.commentThreads.insert" call.
// Exactly one of *CommentThread or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *CommentThread.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 *CommentThreadsInsertCall) Do(opts ...googleapi.CallOption) (*CommentThread, 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 := &CommentThread{
		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": "Inserts a new resource into this collection.",
	//   "flatPath": "youtube/v3/commentThreads",
	//   "httpMethod": "POST",
	//   "id": "youtube.commentThreads.insert",
	//   "parameterOrder": [
	//     "part"
	//   ],
	//   "parameters": {
	//     "part": {
	//       "description": "The *part* parameter identifies the properties that the API response will include. Set the parameter value to snippet. The snippet part has a quota cost of 2 units.",
	//       "location": "query",
	//       "repeated": true,
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "youtube/v3/commentThreads",
	//   "request": {
	//     "$ref": "CommentThread"
	//   },
	//   "response": {
	//     "$ref": "CommentThread"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/youtube.force-ssl"
	//   ]
	// }

}

// method id "youtube.commentThreads.list":

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

// List: Retrieves a list of resources, possibly filtered.
func (r *CommentThreadsService) List(part []string) *CommentThreadsListCall {
	c := &CommentThreadsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.urlParams_.SetMulti("part", append([]string{}, part...))
	return c
}

// AllThreadsRelatedToChannelId sets the optional parameter
// "allThreadsRelatedToChannelId": Returns the comment threads of all
// videos of the channel and the channel comments as well.
func (c *CommentThreadsListCall) AllThreadsRelatedToChannelId(allThreadsRelatedToChannelId string) *CommentThreadsListCall {
	c.urlParams_.Set("allThreadsRelatedToChannelId", allThreadsRelatedToChannelId)
	return c
}

// ChannelId sets the optional parameter "channelId": Returns the
// comment threads for all the channel comments (ie does not include
// comments left on videos).
func (c *CommentThreadsListCall) ChannelId(channelId string) *CommentThreadsListCall {
	c.urlParams_.Set("channelId", channelId)
	return c
}

// Id sets the optional parameter "id": Returns the comment threads with
// the given IDs for Stubby or Apiary.
func (c *CommentThreadsListCall) Id(id ...string) *CommentThreadsListCall {
	c.urlParams_.SetMulti("id", append([]string{}, id...))
	return c
}

// MaxResults sets the optional parameter "maxResults": The *maxResults*
// parameter specifies the maximum number of items that should be
// returned in the result set.
func (c *CommentThreadsListCall) MaxResults(maxResults int64) *CommentThreadsListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// ModerationStatus sets the optional parameter "moderationStatus":
// Limits the returned comment threads to those with the specified
// moderation status. Not compatible with the 'id' filter. Valid values:
// published, heldForReview, likelySpam.
//
// Possible values:
//   "published" (default)
//   "heldForReview"
//   "likelySpam"
//   "rejected"
func (c *CommentThreadsListCall) ModerationStatus(moderationStatus string) *CommentThreadsListCall {
	c.urlParams_.Set("moderationStatus", moderationStatus)
	return c
}

// Order sets the optional parameter "order":
//
// Possible values:
//   "orderUnspecified"
//   "time" (default)
//   "relevance"
func (c *CommentThreadsListCall) Order(order string) *CommentThreadsListCall {
	c.urlParams_.Set("order", order)
	return c
}

// PageToken sets the optional parameter "pageToken": The *pageToken*
// parameter identifies a specific page in the result set that should be
// returned. In an API response, the nextPageToken and prevPageToken
// properties identify other pages that could be retrieved.
func (c *CommentThreadsListCall) PageToken(pageToken string) *CommentThreadsListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// SearchTerms sets the optional parameter "searchTerms": Limits the
// returned comment threads to those matching the specified key words.
// Not compatible with the 'id' filter.
func (c *CommentThreadsListCall) SearchTerms(searchTerms string) *CommentThreadsListCall {
	c.urlParams_.Set("searchTerms", searchTerms)
	return c
}

// TextFormat sets the optional parameter "textFormat": The requested
// text format for the returned comments.
//
// Possible values:
//   "textFormatUnspecified"
//   "html" (default)
//   "plainText"
func (c *CommentThreadsListCall) TextFormat(textFormat string) *CommentThreadsListCall {
	c.urlParams_.Set("textFormat", textFormat)
	return c
}

// VideoId sets the optional parameter "videoId": Returns the comment
// threads of the specified video.
func (c *CommentThreadsListCall) VideoId(videoId string) *CommentThreadsListCall {
	c.urlParams_.Set("videoId", videoId)
	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 *CommentThreadsListCall) Fields(s ...googleapi.Field) *CommentThreadsListCall {
	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 *CommentThreadsListCall) IfNoneMatch(entityTag string) *CommentThreadsListCall {
	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 *CommentThreadsListCall) Context(ctx context.Context) *CommentThreadsListCall {
	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 *CommentThreadsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *CommentThreadsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200912")
	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, "youtube/v3/commentThreads")
	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 "youtube.commentThreads.list" call.
// Exactly one of *CommentThreadListResponse or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *CommentThreadListResponse.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 *CommentThreadsListCall) Do(opts ...googleapi.CallOption) (*CommentThreadListResponse, 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 := &CommentThreadListResponse{
		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": "Retrieves a list of resources, possibly filtered.",
	//   "flatPath": "youtube/v3/commentThreads",
	//   "httpMethod": "GET",
	//   "id": "youtube.commentThreads.list",
	//   "parameterOrder": [
	//     "part"
	//   ],
	//   "parameters": {
	//     "allThreadsRelatedToChannelId": {
	//       "description": "Returns the comment threads of all videos of the channel and the channel comments as well.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "channelId": {
	//       "description": "Returns the comment threads for all the channel comments (ie does not include comments left on videos).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "id": {
	//       "description": "Returns the comment threads with the given IDs for Stubby or Apiary.",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "20",
	//       "description": "The *maxResults* parameter specifies the maximum number of items that should be returned in the result set.",
	//       "format": "uint32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "moderationStatus": {
	//       "default": "published",
	//       "description": "Limits the returned comment threads to those with the specified moderation status. Not compatible with the 'id' filter. Valid values: published, heldForReview, likelySpam.",
	//       "enum": [
	//         "published",
	//         "heldForReview",
	//         "likelySpam",
	//         "rejected"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         "",
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "order": {
	//       "default": "time",
	//       "enum": [
	//         "orderUnspecified",
	//         "time",
	//         "relevance"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageToken": {
	//       "description": "The *pageToken* parameter identifies a specific page in the result set that should be returned. In an API response, the nextPageToken and prevPageToken properties identify other pages that could be retrieved.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "part": {
	//       "description": "The *part* parameter specifies a comma-separated list of one or more commentThread resource properties that the API response will include.",
	//       "location": "query",
	//       "repeated": true,
	//       "required": true,
	//       "type": "string"
	//     },
	//     "searchTerms": {
	//       "description": "Limits the returned comment threads to those matching the specified key words. Not compatible with the 'id' filter.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "textFormat": {
	//       "default": "html",
	//       "description": "The requested text format for the returned comments.",
	//       "enum": [
	//         "textFormatUnspecified",
	//         "html",
	//         "plainText"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "videoId": {
	//       "description": "Returns the comment threads of the specified video.",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "youtube/v3/commentThreads",
	//   "response": {
	//     "$ref": "CommentThreadListResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/youtube.force-ssl"
	//   ]
	// }

}

// 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 *CommentThreadsListCall) Pages(ctx context.Context, f func(*CommentThreadListResponse) 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 "youtube.commentThreads.update":

type CommentThreadsUpdateCall struct {
	s             *Service
	commentthread *CommentThread
	urlParams_    gensupport.URLParams
	ctx_          context.Context
	header_       http.Header
}

// Update: Updates an existing resource.
func (r *CommentThreadsService) Update(part []string, commentthread *CommentThread) *CommentThreadsUpdateCall {
	c := &CommentThreadsUpdateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.urlParams_.SetMulti("part", append([]string{}, part...))
	c.commentthread = commentthread
	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 *CommentThreadsUpdateCall) Fields(s ...googleapi.Field) *CommentThreadsUpdateCall {
	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 *CommentThreadsUpdateCall) Context(ctx context.Context) *CommentThreadsUpdateCall {
	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 *CommentThreadsUpdateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

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

// Do executes the "youtube.commentThreads.update" call.
// Exactly one of *CommentThread or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *CommentThread.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 *CommentThreadsUpdateCall) Do(opts ...googleapi.CallOption) (*CommentThread, 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 := &CommentThread{
		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 existing resource.",
	//   "flatPath": "youtube/v3/commentThreads",
	//   "httpMethod": "PUT",
	//   "id": "youtube.commentThreads.update",
	//   "parameterOrder": [
	//     "part"
	//   ],
	//   "parameters": {
	//     "part": {
	//       "description": "The *part* parameter specifies a comma-separated list of commentThread resource properties that the API response will include. You must at least include the snippet part in the parameter value since that part contains all of the properties that the API request can update.",
	//       "location": "query",
	//       "repeated": true,
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "youtube/v3/commentThreads",
	//   "request": {
	//     "$ref": "CommentThread"
	//   },
	//   "response": {
	//     "$ref": "CommentThread"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/youtube.force-ssl"
	//   ]
	// }

}

// method id "youtube.comments.delete":

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

// Delete: Deletes a resource.
func (r *CommentsService) Delete(id string) *CommentsDeleteCall {
	c := &CommentsDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.urlParams_.Set("id", id)
	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 *CommentsDeleteCall) Fields(s ...googleapi.Field) *CommentsDeleteCall {
	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 *CommentsDeleteCall) Context(ctx context.Context) *CommentsDeleteCall {
	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 *CommentsDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

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

// Do executes the "youtube.comments.delete" call.
func (c *CommentsDeleteCall) Do(opts ...googleapi.CallOption) error {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if err != nil {
		return err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return err
	}
	return nil
	// {
	//   "description": "Deletes a resource.",
	//   "flatPath": "youtube/v3/comments",
	//   "httpMethod": "DELETE",
	//   "id": "youtube.comments.delete",
	//   "parameterOrder": [
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "location": "query",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "youtube/v3/comments",
	//   "scopes": [
	//     "https://www.googleapis.com/auth/youtube.force-ssl"
	//   ]
	// }

}

// method id "youtube.comments.insert":

type CommentsInsertCall struct {
	s          *Service
	comment    *Comment
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Insert: Inserts a new resource into this collection.
func (r *CommentsService) Insert(part []string, comment *Comment) *CommentsInsertCall {
	c := &CommentsInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.urlParams_.SetMulti("part", append([]string{}, part...))
	c.comment = comment
	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 *CommentsInsertCall) Fields(s ...googleapi.Field) *CommentsInsertCall {
	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 *CommentsInsertCall) Context(ctx context.Context) *CommentsInsertCall {
	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 *CommentsInsertCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *CommentsInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200912")
	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.comment)
	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, "youtube/v3/comments")
	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 "youtube.comments.insert" call.
// Exactly one of *Comment or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Comment.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 *CommentsInsertCall) Do(opts ...googleapi.CallOption) (*Comment, 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 := &Comment{
		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": "Inserts a new resource into this collection.",
	//   "flatPath": "youtube/v3/comments",
	//   "httpMethod": "POST",
	//   "id": "youtube.comments.insert",
	//   "parameterOrder": [
	//     "part"
	//   ],
	//   "parameters": {
	//     "part": {
	//       "description": "The *part* parameter identifies the properties that the API response will include. Set the parameter value to snippet. The snippet part has a quota cost of 2 units.",
	//       "location": "query",
	//       "repeated": true,
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "youtube/v3/comments",
	//   "request": {
	//     "$ref": "Comment"
	//   },
	//   "response": {
	//     "$ref": "Comment"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/youtube.force-ssl"
	//   ]
	// }

}

// method id "youtube.comments.list":

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

// List: Retrieves a list of resources, possibly filtered.
func (r *CommentsService) List(part []string) *CommentsListCall {
	c := &CommentsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.urlParams_.SetMulti("part", append([]string{}, part...))
	return c
}

// Id sets the optional parameter "id": Returns the comments with the
// given IDs for One Platform.
func (c *CommentsListCall) Id(id ...string) *CommentsListCall {
	c.urlParams_.SetMulti("id", append([]string{}, id...))
	return c
}

// MaxResults sets the optional parameter "maxResults": The *maxResults*
// parameter specifies the maximum number of items that should be
// returned in the result set.
func (c *CommentsListCall) MaxResults(maxResults int64) *CommentsListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// PageToken sets the optional parameter "pageToken": The *pageToken*
// parameter identifies a specific page in the result set that should be
// returned. In an API response, the nextPageToken and prevPageToken
// properties identify other pages that could be retrieved.
func (c *CommentsListCall) PageToken(pageToken string) *CommentsListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// ParentId sets the optional parameter "parentId": Returns replies to
// the specified comment. Note, currently YouTube features only one
// level of replies (ie replies to top level comments). However replies
// to replies may be supported in the future.
func (c *CommentsListCall) ParentId(parentId string) *CommentsListCall {
	c.urlParams_.Set("parentId", parentId)
	return c
}

// TextFormat sets the optional parameter "textFormat": The requested
// text format for the returned comments.
//
// Possible values:
//   "textFormatUnspecified"
//   "html" (default)
//   "plainText"
func (c *CommentsListCall) TextFormat(textFormat string) *CommentsListCall {
	c.urlParams_.Set("textFormat", textFormat)
	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 *CommentsListCall) Fields(s ...googleapi.Field) *CommentsListCall {
	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 *CommentsListCall) IfNoneMatch(entityTag string) *CommentsListCall {
	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 *CommentsListCall) Context(ctx context.Context) *CommentsListCall {
	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 *CommentsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *CommentsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200912")
	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, "youtube/v3/comments")
	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 "youtube.comments.list" call.
// Exactly one of *CommentListResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *CommentListResponse.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 *CommentsListCall) Do(opts ...googleapi.CallOption) (*CommentListResponse, 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 := &CommentListResponse{
		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": "Retrieves a list of resources, possibly filtered.",
	//   "flatPath": "youtube/v3/comments",
	//   "httpMethod": "GET",
	//   "id": "youtube.comments.list",
	//   "parameterOrder": [
	//     "part"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "Returns the comments with the given IDs for One Platform.",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "20",
	//       "description": "The *maxResults* parameter specifies the maximum number of items that should be returned in the result set.",
	//       "format": "uint32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "The *pageToken* parameter identifies a specific page in the result set that should be returned. In an API response, the nextPageToken and prevPageToken properties identify other pages that could be retrieved.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "parentId": {
	//       "description": "Returns replies to the specified comment. Note, currently YouTube features only one level of replies (ie replies to top level comments). However replies to replies may be supported in the future.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "part": {
	//       "description": "The *part* parameter specifies a comma-separated list of one or more comment resource properties that the API response will include.",
	//       "location": "query",
	//       "repeated": true,
	//       "required": true,
	//       "type": "string"
	//     },
	//     "textFormat": {
	//       "default": "html",
	//       "description": "The requested text format for the returned comments.",
	//       "enum": [
	//         "textFormatUnspecified",
	//         "html",
	//         "plainText"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "youtube/v3/comments",
	//   "response": {
	//     "$ref": "CommentListResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/youtube.force-ssl"
	//   ]
	// }

}

// 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 *CommentsListCall) Pages(ctx context.Context, f func(*CommentListResponse) 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 "youtube.comments.markAsSpam":

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

// MarkAsSpam: Expresses the caller's opinion that one or more comments
// should be flagged as spam.
func (r *CommentsService) MarkAsSpam(id []string) *CommentsMarkAsSpamCall {
	c := &CommentsMarkAsSpamCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.urlParams_.SetMulti("id", append([]string{}, id...))
	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 *CommentsMarkAsSpamCall) Fields(s ...googleapi.Field) *CommentsMarkAsSpamCall {
	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 *CommentsMarkAsSpamCall) Context(ctx context.Context) *CommentsMarkAsSpamCall {
	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 *CommentsMarkAsSpamCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *CommentsMarkAsSpamCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200912")
	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, "youtube/v3/comments/markAsSpam")
	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 "youtube.comments.markAsSpam" call.
func (c *CommentsMarkAsSpamCall) Do(opts ...googleapi.CallOption) error {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if err != nil {
		return err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return err
	}
	return nil
	// {
	//   "description": "Expresses the caller's opinion that one or more comments should be flagged as spam.",
	//   "flatPath": "youtube/v3/comments/markAsSpam",
	//   "httpMethod": "POST",
	//   "id": "youtube.comments.markAsSpam",
	//   "parameterOrder": [
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "Flags the comments with the given IDs as spam in the caller's opinion.",
	//       "location": "query",
	//       "repeated": true,
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "youtube/v3/comments/markAsSpam",
	//   "scopes": [
	//     "https://www.googleapis.com/auth/youtube.force-ssl"
	//   ]
	// }

}

// method id "youtube.comments.setModerationStatus":

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

// SetModerationStatus: Sets the moderation status of one or more
// comments.
func (r *CommentsService) SetModerationStatus(id []string, moderationStatus string) *CommentsSetModerationStatusCall {
	c := &CommentsSetModerationStatusCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.urlParams_.SetMulti("id", append([]string{}, id...))
	c.urlParams_.Set("moderationStatus", moderationStatus)
	return c
}

// BanAuthor sets the optional parameter "banAuthor": If set to true the
// author of the comment gets added to the ban list. This means all
// future comments of the author will autmomatically be rejected. Only
// valid in combination with STATUS_REJECTED.
func (c *CommentsSetModerationStatusCall) BanAuthor(banAuthor bool) *CommentsSetModerationStatusCall {
	c.urlParams_.Set("banAuthor", fmt.Sprint(banAuthor))
	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 *CommentsSetModerationStatusCall) Fields(s ...googleapi.Field) *CommentsSetModerationStatusCall {
	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 *CommentsSetModerationStatusCall) Context(ctx context.Context) *CommentsSetModerationStatusCall {
	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 *CommentsSetModerationStatusCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *CommentsSetModerationStatusCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200912")
	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, "youtube/v3/comments/setModerationStatus")
	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 "youtube.comments.setModerationStatus" call.
func (c *CommentsSetModerationStatusCall) Do(opts ...googleapi.CallOption) error {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if err != nil {
		return err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return err
	}
	return nil
	// {
	//   "description": "Sets the moderation status of one or more comments.",
	//   "flatPath": "youtube/v3/comments/setModerationStatus",
	//   "httpMethod": "POST",
	//   "id": "youtube.comments.setModerationStatus",
	//   "parameterOrder": [
	//     "id",
	//     "moderationStatus"
	//   ],
	//   "parameters": {
	//     "banAuthor": {
	//       "default": "false",
	//       "description": "If set to true the author of the comment gets added to the ban list. This means all future comments of the author will autmomatically be rejected. Only valid in combination with STATUS_REJECTED.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "id": {
	//       "description": "Modifies the moderation status of the comments with the given IDs",
	//       "location": "query",
	//       "repeated": true,
	//       "required": true,
	//       "type": "string"
	//     },
	//     "moderationStatus": {
	//       "description": "Specifies the requested moderation status. Note, comments can be in statuses, which are not available through this call. For example, this call does not allow to mark a comment as 'likely spam'. Valid values: MODERATION_STATUS_PUBLISHED, MODERATION_STATUS_HELD_FOR_REVIEW, MODERATION_STATUS_REJECTED.",
	//       "enum": [
	//         "published",
	//         "heldForReview",
	//         "likelySpam",
	//         "rejected"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         "",
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "youtube/v3/comments/setModerationStatus",
	//   "scopes": [
	//     "https://www.googleapis.com/auth/youtube.force-ssl"
	//   ]
	// }

}

// method id "youtube.comments.update":

type CommentsUpdateCall struct {
	s          *Service
	comment    *Comment
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Update: Updates an existing resource.
func (r *CommentsService) Update(part []string, comment *Comment) *CommentsUpdateCall {
	c := &CommentsUpdateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.urlParams_.SetMulti("part", append([]string{}, part...))
	c.comment = comment
	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 *CommentsUpdateCall) Fields(s ...googleapi.Field) *CommentsUpdateCall {
	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 *CommentsUpdateCall) Context(ctx context.Context) *CommentsUpdateCall {
	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 *CommentsUpdateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

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

// Do executes the "youtube.comments.update" call.
// Exactly one of *Comment or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Comment.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 *CommentsUpdateCall) Do(opts ...googleapi.CallOption) (*Comment, 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 := &Comment{
		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 existing resource.",
	//   "flatPath": "youtube/v3/comments",
	//   "httpMethod": "PUT",
	//   "id": "youtube.comments.update",
	//   "parameterOrder": [
	//     "part"
	//   ],
	//   "parameters": {
	//     "part": {
	//       "description": "The *part* parameter identifies the properties that the API response will include. You must at least include the snippet part in the parameter value since that part contains all of the properties that the API request can update.",
	//       "location": "query",
	//       "repeated": true,
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "youtube/v3/comments",
	//   "request": {
	//     "$ref": "Comment"
	//   },
	//   "response": {
	//     "$ref": "Comment"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/youtube.force-ssl"
	//   ]
	// }

}

// method id "youtube.i18nLanguages.list":

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

// List: Retrieves a list of resources, possibly filtered.
func (r *I18nLanguagesService) List(part []string) *I18nLanguagesListCall {
	c := &I18nLanguagesListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.urlParams_.SetMulti("part", append([]string{}, part...))
	return c
}

// Hl sets the optional parameter "hl":
func (c *I18nLanguagesListCall) Hl(hl string) *I18nLanguagesListCall {
	c.urlParams_.Set("hl", hl)
	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 *I18nLanguagesListCall) Fields(s ...googleapi.Field) *I18nLanguagesListCall {
	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 *I18nLanguagesListCall) IfNoneMatch(entityTag string) *I18nLanguagesListCall {
	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 *I18nLanguagesListCall) Context(ctx context.Context) *I18nLanguagesListCall {
	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 *I18nLanguagesListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *I18nLanguagesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200912")
	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, "youtube/v3/i18nLanguages")
	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 "youtube.i18nLanguages.list" call.
// Exactly one of *I18nLanguageListResponse or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *I18nLanguageListResponse.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 *I18nLanguagesListCall) Do(opts ...googleapi.CallOption) (*I18nLanguageListResponse, 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 := &I18nLanguageListResponse{
		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": "Retrieves a list of resources, possibly filtered.",
	//   "flatPath": "youtube/v3/i18nLanguages",
	//   "httpMethod": "GET",
	//   "id": "youtube.i18nLanguages.list",
	//   "parameterOrder": [
	//     "part"
	//   ],
	//   "parameters": {
	//     "hl": {
	//       "default": "en_US",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "part": {
	//       "description": "The *part* parameter specifies the i18nLanguage resource properties that the API response will include. Set the parameter value to snippet.",
	//       "location": "query",
	//       "repeated": true,
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "youtube/v3/i18nLanguages",
	//   "response": {
	//     "$ref": "I18nLanguageListResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/youtube",
	//     "https://www.googleapis.com/auth/youtube.force-ssl",
	//     "https://www.googleapis.com/auth/youtube.readonly",
	//     "https://www.googleapis.com/auth/youtubepartner"
	//   ]
	// }

}

// method id "youtube.i18nRegions.list":

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

// List: Retrieves a list of resources, possibly filtered.
func (r *I18nRegionsService) List(part []string) *I18nRegionsListCall {
	c := &I18nRegionsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.urlParams_.SetMulti("part", append([]string{}, part...))
	return c
}

// Hl sets the optional parameter "hl":
func (c *I18nRegionsListCall) Hl(hl string) *I18nRegionsListCall {
	c.urlParams_.Set("hl", hl)
	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 *I18nRegionsListCall) Fields(s ...googleapi.Field) *I18nRegionsListCall {
	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 *I18nRegionsListCall) IfNoneMatch(entityTag string) *I18nRegionsListCall {
	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 *I18nRegionsListCall) Context(ctx context.Context) *I18nRegionsListCall {
	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 *I18nRegionsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *I18nRegionsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200912")
	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, "youtube/v3/i18nRegions")
	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 "youtube.i18nRegions.list" call.
// Exactly one of *I18nRegionListResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *I18nRegionListResponse.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 *I18nRegionsListCall) Do(opts ...googleapi.CallOption) (*I18nRegionListResponse, 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 := &I18nRegionListResponse{
		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": "Retrieves a list of resources, possibly filtered.",
	//   "flatPath": "youtube/v3/i18nRegions",
	//   "httpMethod": "GET",
	//   "id": "youtube.i18nRegions.list",
	//   "parameterOrder": [
	//     "part"
	//   ],
	//   "parameters": {
	//     "hl": {
	//       "default": "en_US",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "part": {
	//       "description": "The *part* parameter specifies the i18nRegion resource properties that the API response will include. Set the parameter value to snippet.",
	//       "location": "query",
	//       "repeated": true,
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "youtube/v3/i18nRegions",
	//   "response": {
	//     "$ref": "I18nRegionListResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/youtube",
	//     "https://www.googleapis.com/auth/youtube.force-ssl",
	//     "https://www.googleapis.com/auth/youtube.readonly",
	//     "https://www.googleapis.com/auth/youtubepartner"
	//   ]
	// }

}

// method id "youtube.liveBroadcasts.bind":

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

// Bind: Bind a broadcast to a stream.
func (r *LiveBroadcastsService) Bind(id string, part []string) *LiveBroadcastsBindCall {
	c := &LiveBroadcastsBindCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.urlParams_.Set("id", id)
	c.urlParams_.SetMulti("part", append([]string{}, part...))
	return c
}

// OnBehalfOfContentOwner sets the optional parameter
// "onBehalfOfContentOwner": *Note:* This parameter is intended
// exclusively for YouTube content partners. The
// *onBehalfOfContentOwner* parameter indicates that the request's
// authorization credentials identify a YouTube CMS user who is acting
// on behalf of the content owner specified in the parameter value. This
// parameter is intended for YouTube content partners that own and
// manage many different YouTube channels. It allows content owners to
// authenticate once and get access to all their video and channel data,
// without having to provide authentication credentials for each
// individual channel. The CMS account that the user authenticates with
// must be linked to the specified YouTube content owner.
func (c *LiveBroadcastsBindCall) OnBehalfOfContentOwner(onBehalfOfContentOwner string) *LiveBroadcastsBindCall {
	c.urlParams_.Set("onBehalfOfContentOwner", onBehalfOfContentOwner)
	return c
}

// OnBehalfOfContentOwnerChannel sets the optional parameter
// "onBehalfOfContentOwnerChannel": This parameter can only be used in a
// properly authorized request. *Note:* This parameter is intended
// exclusively for YouTube content partners. The
// *onBehalfOfContentOwnerChannel* parameter specifies the YouTube
// channel ID of the channel to which a video is being added. This
// parameter is required when a request specifies a value for the
// onBehalfOfContentOwner parameter, and it can only be used in
// conjunction with that parameter. In addition, the request must be
// authorized using a CMS account that is linked to the content owner
// that the onBehalfOfContentOwner parameter specifies. Finally, the
// channel that the onBehalfOfContentOwnerChannel parameter value
// specifies must be linked to the content owner that the
// onBehalfOfContentOwner parameter specifies. This parameter is
// intended for YouTube content partners that own and manage many
// different YouTube channels. It allows content owners to authenticate
// once and perform actions on behalf of the channel specified in the
// parameter value, without having to provide authentication credentials
// for each separate channel.
func (c *LiveBroadcastsBindCall) OnBehalfOfContentOwnerChannel(onBehalfOfContentOwnerChannel string) *LiveBroadcastsBindCall {
	c.urlParams_.Set("onBehalfOfContentOwnerChannel", onBehalfOfContentOwnerChannel)
	return c
}

// StreamId sets the optional parameter "streamId": Stream to bind, if
// not set unbind the current one.
func (c *LiveBroadcastsBindCall) StreamId(streamId string) *LiveBroadcastsBindCall {
	c.urlParams_.Set("streamId", streamId)
	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 *LiveBroadcastsBindCall) Fields(s ...googleapi.Field) *LiveBroadcastsBindCall {
	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 *LiveBroadcastsBindCall) Context(ctx context.Context) *LiveBroadcastsBindCall {
	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 *LiveBroadcastsBindCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *LiveBroadcastsBindCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200912")
	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, "youtube/v3/liveBroadcasts/bind")
	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 "youtube.liveBroadcasts.bind" call.
// Exactly one of *LiveBroadcast or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *LiveBroadcast.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 *LiveBroadcastsBindCall) Do(opts ...googleapi.CallOption) (*LiveBroadcast, 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 := &LiveBroadcast{
		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": "Bind a broadcast to a stream.",
	//   "flatPath": "youtube/v3/liveBroadcasts/bind",
	//   "httpMethod": "POST",
	//   "id": "youtube.liveBroadcasts.bind",
	//   "parameterOrder": [
	//     "id",
	//     "part"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "Broadcast to bind to the stream",
	//       "location": "query",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "onBehalfOfContentOwner": {
	//       "description": "*Note:* This parameter is intended exclusively for YouTube content partners. The *onBehalfOfContentOwner* parameter indicates that the request's authorization credentials identify a YouTube CMS user who is acting on behalf of the content owner specified in the parameter value. This parameter is intended for YouTube content partners that own and manage many different YouTube channels. It allows content owners to authenticate once and get access to all their video and channel data, without having to provide authentication credentials for each individual channel. The CMS account that the user authenticates with must be linked to the specified YouTube content owner.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "onBehalfOfContentOwnerChannel": {
	//       "description": "This parameter can only be used in a properly authorized request. *Note:* This parameter is intended exclusively for YouTube content partners. The *onBehalfOfContentOwnerChannel* parameter specifies the YouTube channel ID of the channel to which a video is being added. This parameter is required when a request specifies a value for the onBehalfOfContentOwner parameter, and it can only be used in conjunction with that parameter. In addition, the request must be authorized using a CMS account that is linked to the content owner that the onBehalfOfContentOwner parameter specifies. Finally, the channel that the onBehalfOfContentOwnerChannel parameter value specifies must be linked to the content owner that the onBehalfOfContentOwner parameter specifies. This parameter is intended for YouTube content partners that own and manage many different YouTube channels. It allows content owners to authenticate once and perform actions on behalf of the channel specified in the parameter value, without having to provide authentication credentials for each separate channel.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "part": {
	//       "description": "The *part* parameter specifies a comma-separated list of one or more liveBroadcast resource properties that the API response will include. The part names that you can include in the parameter value are id, snippet, contentDetails, and status.",
	//       "location": "query",
	//       "repeated": true,
	//       "required": true,
	//       "type": "string"
	//     },
	//     "streamId": {
	//       "description": "Stream to bind, if not set unbind the current one.",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "youtube/v3/liveBroadcasts/bind",
	//   "response": {
	//     "$ref": "LiveBroadcast"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/youtube",
	//     "https://www.googleapis.com/auth/youtube.force-ssl"
	//   ]
	// }

}

// method id "youtube.liveBroadcasts.control":

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

// Control: Slate and recording control of the live broadcast. Support
// actions: slate on/off, recording start/stop/pause/resume. Design doc:
// goto/yt-api-liveBroadcast-control
func (r *LiveBroadcastsService) Control(id string, part []string) *LiveBroadcastsControlCall {
	c := &LiveBroadcastsControlCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.urlParams_.Set("id", id)
	c.urlParams_.SetMulti("part", append([]string{}, part...))
	return c
}

// DisplaySlate sets the optional parameter "displaySlate": Whether
// display or hide slate.
func (c *LiveBroadcastsControlCall) DisplaySlate(displaySlate bool) *LiveBroadcastsControlCall {
	c.urlParams_.Set("displaySlate", fmt.Sprint(displaySlate))
	return c
}

// OffsetTimeMs sets the optional parameter "offsetTimeMs": The exact
// time when the actions (e.g. slate on) are executed. It is an offset
// from the first frame of the monitor stream. If not set, it means
// "now" or ASAP. This field should not be set if the monitor stream is
// disabled, otherwise an error will be returned.
func (c *LiveBroadcastsControlCall) OffsetTimeMs(offsetTimeMs uint64) *LiveBroadcastsControlCall {
	c.urlParams_.Set("offsetTimeMs", fmt.Sprint(offsetTimeMs))
	return c
}

// OnBehalfOfContentOwner sets the optional parameter
// "onBehalfOfContentOwner": *Note:* This parameter is intended
// exclusively for YouTube content partners. The
// *onBehalfOfContentOwner* parameter indicates that the request's
// authorization credentials identify a YouTube CMS user who is acting
// on behalf of the content owner specified in the parameter value. This
// parameter is intended for YouTube content partners that own and
// manage many different YouTube channels. It allows content owners to
// authenticate once and get access to all their video and channel data,
// without having to provide authentication credentials for each
// individual channel. The CMS account that the user authenticates with
// must be linked to the specified YouTube content owner.
func (c *LiveBroadcastsControlCall) OnBehalfOfContentOwner(onBehalfOfContentOwner string) *LiveBroadcastsControlCall {
	c.urlParams_.Set("onBehalfOfContentOwner", onBehalfOfContentOwner)
	return c
}

// OnBehalfOfContentOwnerChannel sets the optional parameter
// "onBehalfOfContentOwnerChannel": This parameter can only be used in a
// properly authorized request. *Note:* This parameter is intended
// exclusively for YouTube content partners. The
// *onBehalfOfContentOwnerChannel* parameter specifies the YouTube
// channel ID of the channel to which a video is being added. This
// parameter is required when a request specifies a value for the
// onBehalfOfContentOwner parameter, and it can only be used in
// conjunction with that parameter. In addition, the request must be
// authorized using a CMS account that is linked to the content owner
// that the onBehalfOfContentOwner parameter specifies. Finally, the
// channel that the onBehalfOfContentOwnerChannel parameter value
// specifies must be linked to the content owner that the
// onBehalfOfContentOwner parameter specifies. This parameter is
// intended for YouTube content partners that own and manage many
// different YouTube channels. It allows content owners to authenticate
// once and perform actions on behalf of the channel specified in the
// parameter value, without having to provide authentication credentials
// for each separate channel.
func (c *LiveBroadcastsControlCall) OnBehalfOfContentOwnerChannel(onBehalfOfContentOwnerChannel string) *LiveBroadcastsControlCall {
	c.urlParams_.Set("onBehalfOfContentOwnerChannel", onBehalfOfContentOwnerChannel)
	return c
}

// Walltime sets the optional parameter "walltime": The wall clock time
// at which the action should be executed. Only one of offset_time_ms
// and walltime may be set at a time.
func (c *LiveBroadcastsControlCall) Walltime(walltime string) *LiveBroadcastsControlCall {
	c.urlParams_.Set("walltime", walltime)
	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 *LiveBroadcastsControlCall) Fields(s ...googleapi.Field) *LiveBroadcastsControlCall {
	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 *LiveBroadcastsControlCall) Context(ctx context.Context) *LiveBroadcastsControlCall {
	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 *LiveBroadcastsControlCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *LiveBroadcastsControlCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200912")
	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, "youtube/v3/liveBroadcasts/control")
	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 "youtube.liveBroadcasts.control" call.
// Exactly one of *LiveBroadcast or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *LiveBroadcast.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 *LiveBroadcastsControlCall) Do(opts ...googleapi.CallOption) (*LiveBroadcast, 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 := &LiveBroadcast{
		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": "Slate and recording control of the live broadcast. Support actions: slate on/off, recording start/stop/pause/resume. Design doc: goto/yt-api-liveBroadcast-control",
	//   "flatPath": "youtube/v3/liveBroadcasts/control",
	//   "httpMethod": "POST",
	//   "id": "youtube.liveBroadcasts.control",
	//   "parameterOrder": [
	//     "id",
	//     "part"
	//   ],
	//   "parameters": {
	//     "displaySlate": {
	//       "description": "Whether display or hide slate.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "id": {
	//       "description": "Broadcast to operate.",
	//       "location": "query",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "offsetTimeMs": {
	//       "description": "The exact time when the actions (e.g. slate on) are executed. It is an offset from the first frame of the monitor stream. If not set, it means \"now\" or ASAP. This field should not be set if the monitor stream is disabled, otherwise an error will be returned.",
	//       "format": "uint64",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "onBehalfOfContentOwner": {
	//       "description": "*Note:* This parameter is intended exclusively for YouTube content partners. The *onBehalfOfContentOwner* parameter indicates that the request's authorization credentials identify a YouTube CMS user who is acting on behalf of the content owner specified in the parameter value. This parameter is intended for YouTube content partners that own and manage many different YouTube channels. It allows content owners to authenticate once and get access to all their video and channel data, without having to provide authentication credentials for each individual channel. The CMS account that the user authenticates with must be linked to the specified YouTube content owner.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "onBehalfOfContentOwnerChannel": {
	//       "description": "This parameter can only be used in a properly authorized request. *Note:* This parameter is intended exclusively for YouTube content partners. The *onBehalfOfContentOwnerChannel* parameter specifies the YouTube channel ID of the channel to which a video is being added. This parameter is required when a request specifies a value for the onBehalfOfContentOwner parameter, and it can only be used in conjunction with that parameter. In addition, the request must be authorized using a CMS account that is linked to the content owner that the onBehalfOfContentOwner parameter specifies. Finally, the channel that the onBehalfOfContentOwnerChannel parameter value specifies must be linked to the content owner that the onBehalfOfContentOwner parameter specifies. This parameter is intended for YouTube content partners that own and manage many different YouTube channels. It allows content owners to authenticate once and perform actions on behalf of the channel specified in the parameter value, without having to provide authentication credentials for each separate channel.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "part": {
	//       "description": "The *part* parameter specifies a comma-separated list of one or more liveBroadcast resource properties that the API response will include. The part names that you can include in the parameter value are id, snippet, contentDetails, and status.",
	//       "location": "query",
	//       "repeated": true,
	//       "required": true,
	//       "type": "string"
	//     },
	//     "walltime": {
	//       "description": "The wall clock time at which the action should be executed. Only one of offset_time_ms and walltime may be set at a time.",
	//       "format": "google-datetime",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "youtube/v3/liveBroadcasts/control",
	//   "response": {
	//     "$ref": "LiveBroadcast"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/youtube",
	//     "https://www.googleapis.com/auth/youtube.force-ssl"
	//   ]
	// }

}

// method id "youtube.liveBroadcasts.delete":

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

// Delete: Delete a given broadcast.
func (r *LiveBroadcastsService) Delete(id string) *LiveBroadcastsDeleteCall {
	c := &LiveBroadcastsDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.urlParams_.Set("id", id)
	return c
}

// OnBehalfOfContentOwner sets the optional parameter
// "onBehalfOfContentOwner": *Note:* This parameter is intended
// exclusively for YouTube content partners. The
// *onBehalfOfContentOwner* parameter indicates that the request's
// authorization credentials identify a YouTube CMS user who is acting
// on behalf of the content owner specified in the parameter value. This
// parameter is intended for YouTube content partners that own and
// manage many different YouTube channels. It allows content owners to
// authenticate once and get access to all their video and channel data,
// without having to provide authentication credentials for each
// individual channel. The CMS account that the user authenticates with
// must be linked to the specified YouTube content owner.
func (c *LiveBroadcastsDeleteCall) OnBehalfOfContentOwner(onBehalfOfContentOwner string) *LiveBroadcastsDeleteCall {
	c.urlParams_.Set("onBehalfOfContentOwner", onBehalfOfContentOwner)
	return c
}

// OnBehalfOfContentOwnerChannel sets the optional parameter
// "onBehalfOfContentOwnerChannel": This parameter can only be used in a
// properly authorized request. *Note:* This parameter is intended
// exclusively for YouTube content partners. The
// *onBehalfOfContentOwnerChannel* parameter specifies the YouTube
// channel ID of the channel to which a video is being added. This
// parameter is required when a request specifies a value for the
// onBehalfOfContentOwner parameter, and it can only be used in
// conjunction with that parameter. In addition, the request must be
// authorized using a CMS account that is linked to the content owner
// that the onBehalfOfContentOwner parameter specifies. Finally, the
// channel that the onBehalfOfContentOwnerChannel parameter value
// specifies must be linked to the content owner that the
// onBehalfOfContentOwner parameter specifies. This parameter is
// intended for YouTube content partners that own and manage many
// different YouTube channels. It allows content owners to authenticate
// once and perform actions on behalf of the channel specified in the
// parameter value, without having to provide authentication credentials
// for each separate channel.
func (c *LiveBroadcastsDeleteCall) OnBehalfOfContentOwnerChannel(onBehalfOfContentOwnerChannel string) *LiveBroadcastsDeleteCall {
	c.urlParams_.Set("onBehalfOfContentOwnerChannel", onBehalfOfContentOwnerChannel)
	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 *LiveBroadcastsDeleteCall) Fields(s ...googleapi.Field) *LiveBroadcastsDeleteCall {
	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 *LiveBroadcastsDeleteCall) Context(ctx context.Context) *LiveBroadcastsDeleteCall {
	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 *LiveBroadcastsDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

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

// Do executes the "youtube.liveBroadcasts.delete" call.
func (c *LiveBroadcastsDeleteCall) Do(opts ...googleapi.CallOption) error {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if err != nil {
		return err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return err
	}
	return nil
	// {
	//   "description": "Delete a given broadcast.",
	//   "flatPath": "youtube/v3/liveBroadcasts",
	//   "httpMethod": "DELETE",
	//   "id": "youtube.liveBroadcasts.delete",
	//   "parameterOrder": [
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "Broadcast to delete.",
	//       "location": "query",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "onBehalfOfContentOwner": {
	//       "description": "*Note:* This parameter is intended exclusively for YouTube content partners. The *onBehalfOfContentOwner* parameter indicates that the request's authorization credentials identify a YouTube CMS user who is acting on behalf of the content owner specified in the parameter value. This parameter is intended for YouTube content partners that own and manage many different YouTube channels. It allows content owners to authenticate once and get access to all their video and channel data, without having to provide authentication credentials for each individual channel. The CMS account that the user authenticates with must be linked to the specified YouTube content owner.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "onBehalfOfContentOwnerChannel": {
	//       "description": "This parameter can only be used in a properly authorized request. *Note:* This parameter is intended exclusively for YouTube content partners. The *onBehalfOfContentOwnerChannel* parameter specifies the YouTube channel ID of the channel to which a video is being added. This parameter is required when a request specifies a value for the onBehalfOfContentOwner parameter, and it can only be used in conjunction with that parameter. In addition, the request must be authorized using a CMS account that is linked to the content owner that the onBehalfOfContentOwner parameter specifies. Finally, the channel that the onBehalfOfContentOwnerChannel parameter value specifies must be linked to the content owner that the onBehalfOfContentOwner parameter specifies. This parameter is intended for YouTube content partners that own and manage many different YouTube channels. It allows content owners to authenticate once and perform actions on behalf of the channel specified in the parameter value, without having to provide authentication credentials for each separate channel.",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "youtube/v3/liveBroadcasts",
	//   "scopes": [
	//     "https://www.googleapis.com/auth/youtube",
	//     "https://www.googleapis.com/auth/youtube.force-ssl"
	//   ]
	// }

}

// method id "youtube.liveBroadcasts.insert":

type LiveBroadcastsInsertCall struct {
	s             *Service
	livebroadcast *LiveBroadcast
	urlParams_    gensupport.URLParams
	ctx_          context.Context
	header_       http.Header
}

// Insert: Inserts a new stream for the authenticated user.
func (r *LiveBroadcastsService) Insert(part []string, livebroadcast *LiveBroadcast) *LiveBroadcastsInsertCall {
	c := &LiveBroadcastsInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.urlParams_.SetMulti("part", append([]string{}, part...))
	c.livebroadcast = livebroadcast
	return c
}

// OnBehalfOfContentOwner sets the optional parameter
// "onBehalfOfContentOwner": *Note:* This parameter is intended
// exclusively for YouTube content partners. The
// *onBehalfOfContentOwner* parameter indicates that the request's
// authorization credentials identify a YouTube CMS user who is acting
// on behalf of the content owner specified in the parameter value. This
// parameter is intended for YouTube content partners that own and
// manage many different YouTube channels. It allows content owners to
// authenticate once and get access to all their video and channel data,
// without having to provide authentication credentials for each
// individual channel. The CMS account that the user authenticates with
// must be linked to the specified YouTube content owner.
func (c *LiveBroadcastsInsertCall) OnBehalfOfContentOwner(onBehalfOfContentOwner string) *LiveBroadcastsInsertCall {
	c.urlParams_.Set("onBehalfOfContentOwner", onBehalfOfContentOwner)
	return c
}

// OnBehalfOfContentOwnerChannel sets the optional parameter
// "onBehalfOfContentOwnerChannel": This parameter can only be used in a
// properly authorized request. *Note:* This parameter is intended
// exclusively for YouTube content partners. The
// *onBehalfOfContentOwnerChannel* parameter specifies the YouTube
// channel ID of the channel to which a video is being added. This
// parameter is required when a request specifies a value for the
// onBehalfOfContentOwner parameter, and it can only be used in
// conjunction with that parameter. In addition, the request must be
// authorized using a CMS account that is linked to the content owner
// that the onBehalfOfContentOwner parameter specifies. Finally, the
// channel that the onBehalfOfContentOwnerChannel parameter value
// specifies must be linked to the content owner that the
// onBehalfOfContentOwner parameter specifies. This parameter is
// intended for YouTube content partners that own and manage many
// different YouTube channels. It allows content owners to authenticate
// once and perform actions on behalf of the channel specified in the
// parameter value, without having to provide authentication credentials
// for each separate channel.
func (c *LiveBroadcastsInsertCall) OnBehalfOfContentOwnerChannel(onBehalfOfContentOwnerChannel string) *LiveBroadcastsInsertCall {
	c.urlParams_.Set("onBehalfOfContentOwnerChannel", onBehalfOfContentOwnerChannel)
	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 *LiveBroadcastsInsertCall) Fields(s ...googleapi.Field) *LiveBroadcastsInsertCall {
	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 *LiveBroadcastsInsertCall) Context(ctx context.Context) *LiveBroadcastsInsertCall {
	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 *LiveBroadcastsInsertCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *LiveBroadcastsInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200912")
	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.livebroadcast)
	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, "youtube/v3/liveBroadcasts")
	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 "youtube.liveBroadcasts.insert" call.
// Exactly one of *LiveBroadcast or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *LiveBroadcast.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 *LiveBroadcastsInsertCall) Do(opts ...googleapi.CallOption) (*LiveBroadcast, 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 := &LiveBroadcast{
		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": "Inserts a new stream for the authenticated user.",
	//   "flatPath": "youtube/v3/liveBroadcasts",
	//   "httpMethod": "POST",
	//   "id": "youtube.liveBroadcasts.insert",
	//   "parameterOrder": [
	//     "part"
	//   ],
	//   "parameters": {
	//     "onBehalfOfContentOwner": {
	//       "description": "*Note:* This parameter is intended exclusively for YouTube content partners. The *onBehalfOfContentOwner* parameter indicates that the request's authorization credentials identify a YouTube CMS user who is acting on behalf of the content owner specified in the parameter value. This parameter is intended for YouTube content partners that own and manage many different YouTube channels. It allows content owners to authenticate once and get access to all their video and channel data, without having to provide authentication credentials for each individual channel. The CMS account that the user authenticates with must be linked to the specified YouTube content owner.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "onBehalfOfContentOwnerChannel": {
	//       "description": "This parameter can only be used in a properly authorized request. *Note:* This parameter is intended exclusively for YouTube content partners. The *onBehalfOfContentOwnerChannel* parameter specifies the YouTube channel ID of the channel to which a video is being added. This parameter is required when a request specifies a value for the onBehalfOfContentOwner parameter, and it can only be used in conjunction with that parameter. In addition, the request must be authorized using a CMS account that is linked to the content owner that the onBehalfOfContentOwner parameter specifies. Finally, the channel that the onBehalfOfContentOwnerChannel parameter value specifies must be linked to the content owner that the onBehalfOfContentOwner parameter specifies. This parameter is intended for YouTube content partners that own and manage many different YouTube channels. It allows content owners to authenticate once and perform actions on behalf of the channel specified in the parameter value, without having to provide authentication credentials for each separate channel.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "part": {
	//       "description": "The *part* parameter serves two purposes in this operation. It identifies the properties that the write operation will set as well as the properties that the API response will include. The part properties that you can include in the parameter value are id, snippet, contentDetails, and status.",
	//       "location": "query",
	//       "repeated": true,
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "youtube/v3/liveBroadcasts",
	//   "request": {
	//     "$ref": "LiveBroadcast"
	//   },
	//   "response": {
	//     "$ref": "LiveBroadcast"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/youtube",
	//     "https://www.googleapis.com/auth/youtube.force-ssl"
	//   ]
	// }

}

// method id "youtube.liveBroadcasts.list":

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

// List: Retrieve the list of broadcasts associated with the given
// channel.
func (r *LiveBroadcastsService) List(part []string) *LiveBroadcastsListCall {
	c := &LiveBroadcastsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.urlParams_.SetMulti("part", append([]string{}, part...))
	return c
}

// BroadcastStatus sets the optional parameter "broadcastStatus": Return
// broadcasts with a certain status, e.g. active broadcasts.
//
// Possible values:
//   "broadcastStatusFilterUnspecified"
//   "all"
//   "active"
//   "upcoming"
//   "completed"
func (c *LiveBroadcastsListCall) BroadcastStatus(broadcastStatus string) *LiveBroadcastsListCall {
	c.urlParams_.Set("broadcastStatus", broadcastStatus)
	return c
}

// BroadcastType sets the optional parameter "broadcastType": Return
// only broadcasts with the selected type.
//
// Possible values:
//   "broadcastTypeFilterUnspecified"
//   "all"
//   "event" (default)
//   "persistent"
func (c *LiveBroadcastsListCall) BroadcastType(broadcastType string) *LiveBroadcastsListCall {
	c.urlParams_.Set("broadcastType", broadcastType)
	return c
}

// Id sets the optional parameter "id": Return broadcasts with the given
// ids from Stubby or Apiary.
func (c *LiveBroadcastsListCall) Id(id ...string) *LiveBroadcastsListCall {
	c.urlParams_.SetMulti("id", append([]string{}, id...))
	return c
}

// MaxResults sets the optional parameter "maxResults": The *maxResults*
// parameter specifies the maximum number of items that should be
// returned in the result set.
func (c *LiveBroadcastsListCall) MaxResults(maxResults int64) *LiveBroadcastsListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// Mine sets the optional parameter "mine":
func (c *LiveBroadcastsListCall) Mine(mine bool) *LiveBroadcastsListCall {
	c.urlParams_.Set("mine", fmt.Sprint(mine))
	return c
}

// OnBehalfOfContentOwner sets the optional parameter
// "onBehalfOfContentOwner": *Note:* This parameter is intended
// exclusively for YouTube content partners. The
// *onBehalfOfContentOwner* parameter indicates that the request's
// authorization credentials identify a YouTube CMS user who is acting
// on behalf of the content owner specified in the parameter value. This
// parameter is intended for YouTube content partners that own and
// manage many different YouTube channels. It allows content owners to
// authenticate once and get access to all their video and channel data,
// without having to provide authentication credentials for each
// individual channel. The CMS account that the user authenticates with
// must be linked to the specified YouTube content owner.
func (c *LiveBroadcastsListCall) OnBehalfOfContentOwner(onBehalfOfContentOwner string) *LiveBroadcastsListCall {
	c.urlParams_.Set("onBehalfOfContentOwner", onBehalfOfContentOwner)
	return c
}

// OnBehalfOfContentOwnerChannel sets the optional parameter
// "onBehalfOfContentOwnerChannel": This parameter can only be used in a
// properly authorized request. *Note:* This parameter is intended
// exclusively for YouTube content partners. The
// *onBehalfOfContentOwnerChannel* parameter specifies the YouTube
// channel ID of the channel to which a video is being added. This
// parameter is required when a request specifies a value for the
// onBehalfOfContentOwner parameter, and it can only be used in
// conjunction with that parameter. In addition, the request must be
// authorized using a CMS account that is linked to the content owner
// that the onBehalfOfContentOwner parameter specifies. Finally, the
// channel that the onBehalfOfContentOwnerChannel parameter value
// specifies must be linked to the content owner that the
// onBehalfOfContentOwner parameter specifies. This parameter is
// intended for YouTube content partners that own and manage many
// different YouTube channels. It allows content owners to authenticate
// once and perform actions on behalf of the channel specified in the
// parameter value, without having to provide authentication credentials
// for each separate channel.
func (c *LiveBroadcastsListCall) OnBehalfOfContentOwnerChannel(onBehalfOfContentOwnerChannel string) *LiveBroadcastsListCall {
	c.urlParams_.Set("onBehalfOfContentOwnerChannel", onBehalfOfContentOwnerChannel)
	return c
}

// PageToken sets the optional parameter "pageToken": The *pageToken*
// parameter identifies a specific page in the result set that should be
// returned. In an API response, the nextPageToken and prevPageToken
// properties identify other pages that could be retrieved.
func (c *LiveBroadcastsListCall) PageToken(pageToken string) *LiveBroadcastsListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

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

func (c *LiveBroadcastsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200912")
	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, "youtube/v3/liveBroadcasts")
	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 "youtube.liveBroadcasts.list" call.
// Exactly one of *LiveBroadcastListResponse or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *LiveBroadcastListResponse.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 *LiveBroadcastsListCall) Do(opts ...googleapi.CallOption) (*LiveBroadcastListResponse, 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 := &LiveBroadcastListResponse{
		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": "Retrieve the list of broadcasts associated with the given channel.",
	//   "flatPath": "youtube/v3/liveBroadcasts",
	//   "httpMethod": "GET",
	//   "id": "youtube.liveBroadcasts.list",
	//   "parameterOrder": [
	//     "part"
	//   ],
	//   "parameters": {
	//     "broadcastStatus": {
	//       "description": "Return broadcasts with a certain status, e.g. active broadcasts.",
	//       "enum": [
	//         "broadcastStatusFilterUnspecified",
	//         "all",
	//         "active",
	//         "upcoming",
	//         "completed"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         "",
	//         "",
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "broadcastType": {
	//       "default": "event",
	//       "description": "Return only broadcasts with the selected type.",
	//       "enum": [
	//         "broadcastTypeFilterUnspecified",
	//         "all",
	//         "event",
	//         "persistent"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         "",
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "id": {
	//       "description": "Return broadcasts with the given ids from Stubby or Apiary.",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "5",
	//       "description": "The *maxResults* parameter specifies the maximum number of items that should be returned in the result set.",
	//       "format": "uint32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "mine": {
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "onBehalfOfContentOwner": {
	//       "description": "*Note:* This parameter is intended exclusively for YouTube content partners. The *onBehalfOfContentOwner* parameter indicates that the request's authorization credentials identify a YouTube CMS user who is acting on behalf of the content owner specified in the parameter value. This parameter is intended for YouTube content partners that own and manage many different YouTube channels. It allows content owners to authenticate once and get access to all their video and channel data, without having to provide authentication credentials for each individual channel. The CMS account that the user authenticates with must be linked to the specified YouTube content owner.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "onBehalfOfContentOwnerChannel": {
	//       "description": "This parameter can only be used in a properly authorized request. *Note:* This parameter is intended exclusively for YouTube content partners. The *onBehalfOfContentOwnerChannel* parameter specifies the YouTube channel ID of the channel to which a video is being added. This parameter is required when a request specifies a value for the onBehalfOfContentOwner parameter, and it can only be used in conjunction with that parameter. In addition, the request must be authorized using a CMS account that is linked to the content owner that the onBehalfOfContentOwner parameter specifies. Finally, the channel that the onBehalfOfContentOwnerChannel parameter value specifies must be linked to the content owner that the onBehalfOfContentOwner parameter specifies. This parameter is intended for YouTube content partners that own and manage many different YouTube channels. It allows content owners to authenticate once and perform actions on behalf of the channel specified in the parameter value, without having to provide authentication credentials for each separate channel.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageToken": {
	//       "description": "The *pageToken* parameter identifies a specific page in the result set that should be returned. In an API response, the nextPageToken and prevPageToken properties identify other pages that could be retrieved.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "part": {
	//       "description": "The *part* parameter specifies a comma-separated list of one or more liveBroadcast resource properties that the API response will include. The part names that you can include in the parameter value are id, snippet, contentDetails, and status.",
	//       "location": "query",
	//       "repeated": true,
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "youtube/v3/liveBroadcasts",
	//   "response": {
	//     "$ref": "LiveBroadcastListResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/youtube",
	//     "https://www.googleapis.com/auth/youtube.force-ssl",
	//     "https://www.googleapis.com/auth/youtube.readonly"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *LiveBroadcastsListCall) Pages(ctx context.Context, f func(*LiveBroadcastListResponse) 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 "youtube.liveBroadcasts.transition":

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

// Transition: Transition a broadcast to a given status.
func (r *LiveBroadcastsService) Transition(id string, broadcastStatus string, part []string) *LiveBroadcastsTransitionCall {
	c := &LiveBroadcastsTransitionCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.urlParams_.Set("id", id)
	c.urlParams_.Set("broadcastStatus", broadcastStatus)
	c.urlParams_.SetMulti("part", append([]string{}, part...))
	return c
}

// OnBehalfOfContentOwner sets the optional parameter
// "onBehalfOfContentOwner": *Note:* This parameter is intended
// exclusively for YouTube content partners. The
// *onBehalfOfContentOwner* parameter indicates that the request's
// authorization credentials identify a YouTube CMS user who is acting
// on behalf of the content owner specified in the parameter value. This
// parameter is intended for YouTube content partners that own and
// manage many different YouTube channels. It allows content owners to
// authenticate once and get access to all their video and channel data,
// without having to provide authentication credentials for each
// individual channel. The CMS account that the user authenticates with
// must be linked to the specified YouTube content owner.
func (c *LiveBroadcastsTransitionCall) OnBehalfOfContentOwner(onBehalfOfContentOwner string) *LiveBroadcastsTransitionCall {
	c.urlParams_.Set("onBehalfOfContentOwner", onBehalfOfContentOwner)
	return c
}

// OnBehalfOfContentOwnerChannel sets the optional parameter
// "onBehalfOfContentOwnerChannel": This parameter can only be used in a
// properly authorized request. *Note:* This parameter is intended
// exclusively for YouTube content partners. The
// *onBehalfOfContentOwnerChannel* parameter specifies the YouTube
// channel ID of the channel to which a video is being added. This
// parameter is required when a request specifies a value for the
// onBehalfOfContentOwner parameter, and it can only be used in
// conjunction with that parameter. In addition, the request must be
// authorized using a CMS account that is linked to the content owner
// that the onBehalfOfContentOwner parameter specifies. Finally, the
// channel that the onBehalfOfContentOwnerChannel parameter value
// specifies must be linked to the content owner that the
// onBehalfOfContentOwner parameter specifies. This parameter is
// intended for YouTube content partners that own and manage many
// different YouTube channels. It allows content owners to authenticate
// once and perform actions on behalf of the channel specified in the
// parameter value, without having to provide authentication credentials
// for each separate channel.
func (c *LiveBroadcastsTransitionCall) OnBehalfOfContentOwnerChannel(onBehalfOfContentOwnerChannel string) *LiveBroadcastsTransitionCall {
	c.urlParams_.Set("onBehalfOfContentOwnerChannel", onBehalfOfContentOwnerChannel)
	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 *LiveBroadcastsTransitionCall) Fields(s ...googleapi.Field) *LiveBroadcastsTransitionCall {
	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 *LiveBroadcastsTransitionCall) Context(ctx context.Context) *LiveBroadcastsTransitionCall {
	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 *LiveBroadcastsTransitionCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *LiveBroadcastsTransitionCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200912")
	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, "youtube/v3/liveBroadcasts/transition")
	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 "youtube.liveBroadcasts.transition" call.
// Exactly one of *LiveBroadcast or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *LiveBroadcast.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 *LiveBroadcastsTransitionCall) Do(opts ...googleapi.CallOption) (*LiveBroadcast, 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 := &LiveBroadcast{
		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": "Transition a broadcast to a given status.",
	//   "flatPath": "youtube/v3/liveBroadcasts/transition",
	//   "httpMethod": "POST",
	//   "id": "youtube.liveBroadcasts.transition",
	//   "parameterOrder": [
	//     "id",
	//     "broadcastStatus",
	//     "part"
	//   ],
	//   "parameters": {
	//     "broadcastStatus": {
	//       "description": "The status to which the broadcast is going to transition.",
	//       "enum": [
	//         "statusUnspecified",
	//         "testing",
	//         "live",
	//         "complete"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         "",
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "id": {
	//       "description": "Broadcast to transition.",
	//       "location": "query",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "onBehalfOfContentOwner": {
	//       "description": "*Note:* This parameter is intended exclusively for YouTube content partners. The *onBehalfOfContentOwner* parameter indicates that the request's authorization credentials identify a YouTube CMS user who is acting on behalf of the content owner specified in the parameter value. This parameter is intended for YouTube content partners that own and manage many different YouTube channels. It allows content owners to authenticate once and get access to all their video and channel data, without having to provide authentication credentials for each individual channel. The CMS account that the user authenticates with must be linked to the specified YouTube content owner.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "onBehalfOfContentOwnerChannel": {
	//       "description": "This parameter can only be used in a properly authorized request. *Note:* This parameter is intended exclusively for YouTube content partners. The *onBehalfOfContentOwnerChannel* parameter specifies the YouTube channel ID of the channel to which a video is being added. This parameter is required when a request specifies a value for the onBehalfOfContentOwner parameter, and it can only be used in conjunction with that parameter. In addition, the request must be authorized using a CMS account that is linked to the content owner that the onBehalfOfContentOwner parameter specifies. Finally, the channel that the onBehalfOfContentOwnerChannel parameter value specifies must be linked to the content owner that the onBehalfOfContentOwner parameter specifies. This parameter is intended for YouTube content partners that own and manage many different YouTube channels. It allows content owners to authenticate once and perform actions on behalf of the channel specified in the parameter value, without having to provide authentication credentials for each separate channel.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "part": {
	//       "description": "The *part* parameter specifies a comma-separated list of one or more liveBroadcast resource properties that the API response will include. The part names that you can include in the parameter value are id, snippet, contentDetails, and status.",
	//       "location": "query",
	//       "repeated": true,
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "youtube/v3/liveBroadcasts/transition",
	//   "response": {
	//     "$ref": "LiveBroadcast"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/youtube",
	//     "https://www.googleapis.com/auth/youtube.force-ssl"
	//   ]
	// }

}

// method id "youtube.liveBroadcasts.update":

type LiveBroadcastsUpdateCall struct {
	s             *Service
	livebroadcast *LiveBroadcast
	urlParams_    gensupport.URLParams
	ctx_          context.Context
	header_       http.Header
}

// Update: Updates an existing broadcast for the authenticated user.
func (r *LiveBroadcastsService) Update(part []string, livebroadcast *LiveBroadcast) *LiveBroadcastsUpdateCall {
	c := &LiveBroadcastsUpdateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.urlParams_.SetMulti("part", append([]string{}, part...))
	c.livebroadcast = livebroadcast
	return c
}

// OnBehalfOfContentOwner sets the optional parameter
// "onBehalfOfContentOwner": *Note:* This parameter is intended
// exclusively for YouTube content partners. The
// *onBehalfOfContentOwner* parameter indicates that the request's
// authorization credentials identify a YouTube CMS user who is acting
// on behalf of the content owner specified in the parameter value. This
// parameter is intended for YouTube content partners that own and
// manage many different YouTube channels. It allows content owners to
// authenticate once and get access to all their video and channel data,
// without having to provide authentication credentials for each
// individual channel. The CMS account that the user authenticates with
// must be linked to the specified YouTube content owner.
func (c *LiveBroadcastsUpdateCall) OnBehalfOfContentOwner(onBehalfOfContentOwner string) *LiveBroadcastsUpdateCall {
	c.urlParams_.Set("onBehalfOfContentOwner", onBehalfOfContentOwner)
	return c
}

// OnBehalfOfContentOwnerChannel sets the optional parameter
// "onBehalfOfContentOwnerChannel": This parameter can only be used in a
// properly authorized request. *Note:* This parameter is intended
// exclusively for YouTube content partners. The
// *onBehalfOfContentOwnerChannel* parameter specifies the YouTube
// channel ID of the channel to which a video is being added. This
// parameter is required when a request specifies a value for the
// onBehalfOfContentOwner parameter, and it can only be used in
// conjunction with that parameter. In addition, the request must be
// authorized using a CMS account that is linked to the content owner
// that the onBehalfOfContentOwner parameter specifies. Finally, the
// channel that the onBehalfOfContentOwnerChannel parameter value
// specifies must be linked to the content owner that the
// onBehalfOfContentOwner parameter specifies. This parameter is
// intended for YouTube content partners that own and manage many
// different YouTube channels. It allows content owners to authenticate
// once and perform actions on behalf of the channel specified in the
// parameter value, without having to provide authentication credentials
// for each separate channel.
func (c *LiveBroadcastsUpdateCall) OnBehalfOfContentOwnerChannel(onBehalfOfContentOwnerChannel string) *LiveBroadcastsUpdateCall {
	c.urlParams_.Set("onBehalfOfContentOwnerChannel", onBehalfOfContentOwnerChannel)
	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 *LiveBroadcastsUpdateCall) Fields(s ...googleapi.Field) *LiveBroadcastsUpdateCall {
	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 *LiveBroadcastsUpdateCall) Context(ctx context.Context) *LiveBroadcastsUpdateCall {
	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 *LiveBroadcastsUpdateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

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

// Do executes the "youtube.liveBroadcasts.update" call.
// Exactly one of *LiveBroadcast or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *LiveBroadcast.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 *LiveBroadcastsUpdateCall) Do(opts ...googleapi.CallOption) (*LiveBroadcast, 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 := &LiveBroadcast{
		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 existing broadcast for the authenticated user.",
	//   "flatPath": "youtube/v3/liveBroadcasts",
	//   "httpMethod": "PUT",
	//   "id": "youtube.liveBroadcasts.update",
	//   "parameterOrder": [
	//     "part"
	//   ],
	//   "parameters": {
	//     "onBehalfOfContentOwner": {
	//       "description": "*Note:* This parameter is intended exclusively for YouTube content partners. The *onBehalfOfContentOwner* parameter indicates that the request's authorization credentials identify a YouTube CMS user who is acting on behalf of the content owner specified in the parameter value. This parameter is intended for YouTube content partners that own and manage many different YouTube channels. It allows content owners to authenticate once and get access to all their video and channel data, without having to provide authentication credentials for each individual channel. The CMS account that the user authenticates with must be linked to the specified YouTube content owner.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "onBehalfOfContentOwnerChannel": {
	//       "description": "This parameter can only be used in a properly authorized request. *Note:* This parameter is intended exclusively for YouTube content partners. The *onBehalfOfContentOwnerChannel* parameter specifies the YouTube channel ID of the channel to which a video is being added. This parameter is required when a request specifies a value for the onBehalfOfContentOwner parameter, and it can only be used in conjunction with that parameter. In addition, the request must be authorized using a CMS account that is linked to the content owner that the onBehalfOfContentOwner parameter specifies. Finally, the channel that the onBehalfOfContentOwnerChannel parameter value specifies must be linked to the content owner that the onBehalfOfContentOwner parameter specifies. This parameter is intended for YouTube content partners that own and manage many different YouTube channels. It allows content owners to authenticate once and perform actions on behalf of the channel specified in the parameter value, without having to provide authentication credentials for each separate channel.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "part": {
	//       "description": "The *part* parameter serves two purposes in this operation. It identifies the properties that the write operation will set as well as the properties that the API response will include. The part properties that you can include in the parameter value are id, snippet, contentDetails, and status. Note that this method will override the existing values for all of the mutable properties that are contained in any parts that the parameter value specifies. For example, a broadcast's privacy status is defined in the status part. As such, if your request is updating a private or unlisted broadcast, and the request's part parameter value includes the status part, the broadcast's privacy setting will be updated to whatever value the request body specifies. If the request body does not specify a value, the existing privacy setting will be removed and the broadcast will revert to the default privacy setting.",
	//       "location": "query",
	//       "repeated": true,
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "youtube/v3/liveBroadcasts",
	//   "request": {
	//     "$ref": "LiveBroadcast"
	//   },
	//   "response": {
	//     "$ref": "LiveBroadcast"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/youtube",
	//     "https://www.googleapis.com/auth/youtube.force-ssl"
	//   ]
	// }

}

// method id "youtube.liveChatBans.delete":

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

// Delete: Deletes a chat ban.
func (r *LiveChatBansService) Delete(id string) *LiveChatBansDeleteCall {
	c := &LiveChatBansDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.urlParams_.Set("id", id)
	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 *LiveChatBansDeleteCall) Fields(s ...googleapi.Field) *LiveChatBansDeleteCall {
	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 *LiveChatBansDeleteCall) Context(ctx context.Context) *LiveChatBansDeleteCall {
	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 *LiveChatBansDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

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

// Do executes the "youtube.liveChatBans.delete" call.
func (c *LiveChatBansDeleteCall) Do(opts ...googleapi.CallOption) error {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if err != nil {
		return err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return err
	}
	return nil
	// {
	//   "description": "Deletes a chat ban.",
	//   "flatPath": "youtube/v3/liveChat/bans",
	//   "httpMethod": "DELETE",
	//   "id": "youtube.liveChatBans.delete",
	//   "parameterOrder": [
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "location": "query",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "youtube/v3/liveChat/bans",
	//   "scopes": [
	//     "https://www.googleapis.com/auth/youtube",
	//     "https://www.googleapis.com/auth/youtube.force-ssl"
	//   ]
	// }

}

// method id "youtube.liveChatBans.insert":

type LiveChatBansInsertCall struct {
	s           *Service
	livechatban *LiveChatBan
	urlParams_  gensupport.URLParams
	ctx_        context.Context
	header_     http.Header
}

// Insert: Inserts a new resource into this collection.
func (r *LiveChatBansService) Insert(part []string, livechatban *LiveChatBan) *LiveChatBansInsertCall {
	c := &LiveChatBansInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.urlParams_.SetMulti("part", append([]string{}, part...))
	c.livechatban = livechatban
	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 *LiveChatBansInsertCall) Fields(s ...googleapi.Field) *LiveChatBansInsertCall {
	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 *LiveChatBansInsertCall) Context(ctx context.Context) *LiveChatBansInsertCall {
	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 *LiveChatBansInsertCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *LiveChatBansInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200912")
	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.livechatban)
	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, "youtube/v3/liveChat/bans")
	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 "youtube.liveChatBans.insert" call.
// Exactly one of *LiveChatBan or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *LiveChatBan.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 *LiveChatBansInsertCall) Do(opts ...googleapi.CallOption) (*LiveChatBan, 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 := &LiveChatBan{
		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": "Inserts a new resource into this collection.",
	//   "flatPath": "youtube/v3/liveChat/bans",
	//   "httpMethod": "POST",
	//   "id": "youtube.liveChatBans.insert",
	//   "parameterOrder": [
	//     "part"
	//   ],
	//   "parameters": {
	//     "part": {
	//       "description": "The *part* parameter serves two purposes in this operation. It identifies the properties that the write operation will set as well as the properties that the API response returns. Set the parameter value to snippet.",
	//       "location": "query",
	//       "repeated": true,
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "youtube/v3/liveChat/bans",
	//   "request": {
	//     "$ref": "LiveChatBan"
	//   },
	//   "response": {
	//     "$ref": "LiveChatBan"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/youtube",
	//     "https://www.googleapis.com/auth/youtube.force-ssl"
	//   ]
	// }

}

// method id "youtube.liveChatMessages.delete":

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

// Delete: Deletes a chat message.
func (r *LiveChatMessagesService) Delete(id string) *LiveChatMessagesDeleteCall {
	c := &LiveChatMessagesDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.urlParams_.Set("id", id)
	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 *LiveChatMessagesDeleteCall) Fields(s ...googleapi.Field) *LiveChatMessagesDeleteCall {
	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 *LiveChatMessagesDeleteCall) Context(ctx context.Context) *LiveChatMessagesDeleteCall {
	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 *LiveChatMessagesDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

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

// Do executes the "youtube.liveChatMessages.delete" call.
func (c *LiveChatMessagesDeleteCall) Do(opts ...googleapi.CallOption) error {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if err != nil {
		return err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return err
	}
	return nil
	// {
	//   "description": "Deletes a chat message.",
	//   "flatPath": "youtube/v3/liveChat/messages",
	//   "httpMethod": "DELETE",
	//   "id": "youtube.liveChatMessages.delete",
	//   "parameterOrder": [
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "location": "query",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "youtube/v3/liveChat/messages",
	//   "scopes": [
	//     "https://www.googleapis.com/auth/youtube",
	//     "https://www.googleapis.com/auth/youtube.force-ssl"
	//   ]
	// }

}

// method id "youtube.liveChatMessages.insert":

type LiveChatMessagesInsertCall struct {
	s               *Service
	livechatmessage *LiveChatMessage
	urlParams_      gensupport.URLParams
	ctx_            context.Context
	header_         http.Header
}

// Insert: Inserts a new resource into this collection.
func (r *LiveChatMessagesService) Insert(part []string, livechatmessage *LiveChatMessage) *LiveChatMessagesInsertCall {
	c := &LiveChatMessagesInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.urlParams_.SetMulti("part", append([]string{}, part...))
	c.livechatmessage = livechatmessage
	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 *LiveChatMessagesInsertCall) Fields(s ...googleapi.Field) *LiveChatMessagesInsertCall {
	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 *LiveChatMessagesInsertCall) Context(ctx context.Context) *LiveChatMessagesInsertCall {
	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 *LiveChatMessagesInsertCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *LiveChatMessagesInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200912")
	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.livechatmessage)
	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, "youtube/v3/liveChat/messages")
	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 "youtube.liveChatMessages.insert" call.
// Exactly one of *LiveChatMessage or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *LiveChatMessage.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 *LiveChatMessagesInsertCall) Do(opts ...googleapi.CallOption) (*LiveChatMessage, 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 := &LiveChatMessage{
		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": "Inserts a new resource into this collection.",
	//   "flatPath": "youtube/v3/liveChat/messages",
	//   "httpMethod": "POST",
	//   "id": "youtube.liveChatMessages.insert",
	//   "parameterOrder": [
	//     "part"
	//   ],
	//   "parameters": {
	//     "part": {
	//       "description": "The *part* parameter serves two purposes. It identifies the properties that the write operation will set as well as the properties that the API response will include. Set the parameter value to snippet.",
	//       "location": "query",
	//       "repeated": true,
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "youtube/v3/liveChat/messages",
	//   "request": {
	//     "$ref": "LiveChatMessage"
	//   },
	//   "response": {
	//     "$ref": "LiveChatMessage"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/youtube",
	//     "https://www.googleapis.com/auth/youtube.force-ssl"
	//   ]
	// }

}

// method id "youtube.liveChatMessages.list":

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

// List: Retrieves a list of resources, possibly filtered.
func (r *LiveChatMessagesService) List(liveChatId string, part []string) *LiveChatMessagesListCall {
	c := &LiveChatMessagesListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.urlParams_.Set("liveChatId", liveChatId)
	c.urlParams_.SetMulti("part", append([]string{}, part...))
	return c
}

// Hl sets the optional parameter "hl": Specifies the localization
// language in which the system messages should be returned.
func (c *LiveChatMessagesListCall) Hl(hl string) *LiveChatMessagesListCall {
	c.urlParams_.Set("hl", hl)
	return c
}

// MaxResults sets the optional parameter "maxResults": The *maxResults*
// parameter specifies the maximum number of items that should be
// returned in the result set.
func (c *LiveChatMessagesListCall) MaxResults(maxResults int64) *LiveChatMessagesListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// PageToken sets the optional parameter "pageToken": The *pageToken*
// parameter identifies a specific page in the result set that should be
// returned. In an API response, the nextPageToken property identify
// other pages that could be retrieved.
func (c *LiveChatMessagesListCall) PageToken(pageToken string) *LiveChatMessagesListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// ProfileImageSize sets the optional parameter "profileImageSize":
// Specifies the size of the profile image that should be returned for
// each user.
func (c *LiveChatMessagesListCall) ProfileImageSize(profileImageSize int64) *LiveChatMessagesListCall {
	c.urlParams_.Set("profileImageSize", fmt.Sprint(profileImageSize))
	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 *LiveChatMessagesListCall) Fields(s ...googleapi.Field) *LiveChatMessagesListCall {
	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 *LiveChatMessagesListCall) IfNoneMatch(entityTag string) *LiveChatMessagesListCall {
	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 *LiveChatMessagesListCall) Context(ctx context.Context) *LiveChatMessagesListCall {
	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 *LiveChatMessagesListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *LiveChatMessagesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200912")
	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, "youtube/v3/liveChat/messages")
	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 "youtube.liveChatMessages.list" call.
// Exactly one of *LiveChatMessageListResponse or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *LiveChatMessageListResponse.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 *LiveChatMessagesListCall) Do(opts ...googleapi.CallOption) (*LiveChatMessageListResponse, 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 := &LiveChatMessageListResponse{
		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": "Retrieves a list of resources, possibly filtered.",
	//   "flatPath": "youtube/v3/liveChat/messages",
	//   "httpMethod": "GET",
	//   "id": "youtube.liveChatMessages.list",
	//   "parameterOrder": [
	//     "liveChatId",
	//     "part"
	//   ],
	//   "parameters": {
	//     "hl": {
	//       "description": "Specifies the localization language in which the system messages should be returned.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "liveChatId": {
	//       "description": "The id of the live chat for which comments should be returned.",
	//       "location": "query",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "500",
	//       "description": "The *maxResults* parameter specifies the maximum number of items that should be returned in the result set.",
	//       "format": "uint32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "The *pageToken* parameter identifies a specific page in the result set that should be returned. In an API response, the nextPageToken property identify other pages that could be retrieved.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "part": {
	//       "description": "The *part* parameter specifies the liveChatComment resource parts that the API response will include. Supported values are id and snippet.",
	//       "location": "query",
	//       "repeated": true,
	//       "required": true,
	//       "type": "string"
	//     },
	//     "profileImageSize": {
	//       "description": "Specifies the size of the profile image that should be returned for each user.",
	//       "format": "uint32",
	//       "location": "query",
	//       "type": "integer"
	//     }
	//   },
	//   "path": "youtube/v3/liveChat/messages",
	//   "response": {
	//     "$ref": "LiveChatMessageListResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/youtube",
	//     "https://www.googleapis.com/auth/youtube.force-ssl",
	//     "https://www.googleapis.com/auth/youtube.readonly"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *LiveChatMessagesListCall) Pages(ctx context.Context, f func(*LiveChatMessageListResponse) 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 "youtube.liveChatModerators.delete":

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

// Delete: Deletes a chat moderator.
func (r *LiveChatModeratorsService) Delete(id string) *LiveChatModeratorsDeleteCall {
	c := &LiveChatModeratorsDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.urlParams_.Set("id", id)
	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 *LiveChatModeratorsDeleteCall) Fields(s ...googleapi.Field) *LiveChatModeratorsDeleteCall {
	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 *LiveChatModeratorsDeleteCall) Context(ctx context.Context) *LiveChatModeratorsDeleteCall {
	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 *LiveChatModeratorsDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

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

// Do executes the "youtube.liveChatModerators.delete" call.
func (c *LiveChatModeratorsDeleteCall) Do(opts ...googleapi.CallOption) error {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if err != nil {
		return err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return err
	}
	return nil
	// {
	//   "description": "Deletes a chat moderator.",
	//   "flatPath": "youtube/v3/liveChat/moderators",
	//   "httpMethod": "DELETE",
	//   "id": "youtube.liveChatModerators.delete",
	//   "parameterOrder": [
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "location": "query",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "youtube/v3/liveChat/moderators",
	//   "scopes": [
	//     "https://www.googleapis.com/auth/youtube",
	//     "https://www.googleapis.com/auth/youtube.force-ssl"
	//   ]
	// }

}

// method id "youtube.liveChatModerators.insert":

type LiveChatModeratorsInsertCall struct {
	s                 *Service
	livechatmoderator *LiveChatModerator
	urlParams_        gensupport.URLParams
	ctx_              context.Context
	header_           http.Header
}

// Insert: Inserts a new resource into this collection.
func (r *LiveChatModeratorsService) Insert(part []string, livechatmoderator *LiveChatModerator) *LiveChatModeratorsInsertCall {
	c := &LiveChatModeratorsInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.urlParams_.SetMulti("part", append([]string{}, part...))
	c.livechatmoderator = livechatmoderator
	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 *LiveChatModeratorsInsertCall) Fields(s ...googleapi.Field) *LiveChatModeratorsInsertCall {
	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 *LiveChatModeratorsInsertCall) Context(ctx context.Context) *LiveChatModeratorsInsertCall {
	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 *LiveChatModeratorsInsertCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *LiveChatModeratorsInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200912")
	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.livechatmoderator)
	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, "youtube/v3/liveChat/moderators")
	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 "youtube.liveChatModerators.insert" call.
// Exactly one of *LiveChatModerator or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *LiveChatModerator.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 *LiveChatModeratorsInsertCall) Do(opts ...googleapi.CallOption) (*LiveChatModerator, 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 := &LiveChatModerator{
		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": "Inserts a new resource into this collection.",
	//   "flatPath": "youtube/v3/liveChat/moderators",
	//   "httpMethod": "POST",
	//   "id": "youtube.liveChatModerators.insert",
	//   "parameterOrder": [
	//     "part"
	//   ],
	//   "parameters": {
	//     "part": {
	//       "description": "The *part* parameter serves two purposes in this operation. It identifies the properties that the write operation will set as well as the properties that the API response returns. Set the parameter value to snippet.",
	//       "location": "query",
	//       "repeated": true,
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "youtube/v3/liveChat/moderators",
	//   "request": {
	//     "$ref": "LiveChatModerator"
	//   },
	//   "response": {
	//     "$ref": "LiveChatModerator"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/youtube",
	//     "https://www.googleapis.com/auth/youtube.force-ssl"
	//   ]
	// }

}

// method id "youtube.liveChatModerators.list":

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

// List: Retrieves a list of resources, possibly filtered.
func (r *LiveChatModeratorsService) List(liveChatId string, part []string) *LiveChatModeratorsListCall {
	c := &LiveChatModeratorsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.urlParams_.Set("liveChatId", liveChatId)
	c.urlParams_.SetMulti("part", append([]string{}, part...))
	return c
}

// MaxResults sets the optional parameter "maxResults": The *maxResults*
// parameter specifies the maximum number of items that should be
// returned in the result set.
func (c *LiveChatModeratorsListCall) MaxResults(maxResults int64) *LiveChatModeratorsListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// PageToken sets the optional parameter "pageToken": The *pageToken*
// parameter identifies a specific page in the result set that should be
// returned. In an API response, the nextPageToken and prevPageToken
// properties identify other pages that could be retrieved.
func (c *LiveChatModeratorsListCall) PageToken(pageToken string) *LiveChatModeratorsListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

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

func (c *LiveChatModeratorsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200912")
	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, "youtube/v3/liveChat/moderators")
	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 "youtube.liveChatModerators.list" call.
// Exactly one of *LiveChatModeratorListResponse or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *LiveChatModeratorListResponse.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 *LiveChatModeratorsListCall) Do(opts ...googleapi.CallOption) (*LiveChatModeratorListResponse, 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 := &LiveChatModeratorListResponse{
		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": "Retrieves a list of resources, possibly filtered.",
	//   "flatPath": "youtube/v3/liveChat/moderators",
	//   "httpMethod": "GET",
	//   "id": "youtube.liveChatModerators.list",
	//   "parameterOrder": [
	//     "liveChatId",
	//     "part"
	//   ],
	//   "parameters": {
	//     "liveChatId": {
	//       "description": "The id of the live chat for which moderators should be returned.",
	//       "location": "query",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "5",
	//       "description": "The *maxResults* parameter specifies the maximum number of items that should be returned in the result set.",
	//       "format": "uint32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "The *pageToken* parameter identifies a specific page in the result set that should be returned. In an API response, the nextPageToken and prevPageToken properties identify other pages that could be retrieved.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "part": {
	//       "description": "The *part* parameter specifies the liveChatModerator resource parts that the API response will include. Supported values are id and snippet.",
	//       "location": "query",
	//       "repeated": true,
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "youtube/v3/liveChat/moderators",
	//   "response": {
	//     "$ref": "LiveChatModeratorListResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/youtube",
	//     "https://www.googleapis.com/auth/youtube.force-ssl",
	//     "https://www.googleapis.com/auth/youtube.readonly"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *LiveChatModeratorsListCall) Pages(ctx context.Context, f func(*LiveChatModeratorListResponse) 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 "youtube.liveStreams.delete":

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

// Delete: Deletes an existing stream for the authenticated user.
func (r *LiveStreamsService) Delete(id string) *LiveStreamsDeleteCall {
	c := &LiveStreamsDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.urlParams_.Set("id", id)
	return c
}

// OnBehalfOfContentOwner sets the optional parameter
// "onBehalfOfContentOwner": *Note:* This parameter is intended
// exclusively for YouTube content partners. The
// *onBehalfOfContentOwner* parameter indicates that the request's
// authorization credentials identify a YouTube CMS user who is acting
// on behalf of the content owner specified in the parameter value. This
// parameter is intended for YouTube content partners that own and
// manage many different YouTube channels. It allows content owners to
// authenticate once and get access to all their video and channel data,
// without having to provide authentication credentials for each
// individual channel. The CMS account that the user authenticates with
// must be linked to the specified YouTube content owner.
func (c *LiveStreamsDeleteCall) OnBehalfOfContentOwner(onBehalfOfContentOwner string) *LiveStreamsDeleteCall {
	c.urlParams_.Set("onBehalfOfContentOwner", onBehalfOfContentOwner)
	return c
}

// OnBehalfOfContentOwnerChannel sets the optional parameter
// "onBehalfOfContentOwnerChannel": This parameter can only be used in a
// properly authorized request. *Note:* This parameter is intended
// exclusively for YouTube content partners. The
// *onBehalfOfContentOwnerChannel* parameter specifies the YouTube
// channel ID of the channel to which a video is being added. This
// parameter is required when a request specifies a value for the
// onBehalfOfContentOwner parameter, and it can only be used in
// conjunction with that parameter. In addition, the request must be
// authorized using a CMS account that is linked to the content owner
// that the onBehalfOfContentOwner parameter specifies. Finally, the
// channel that the onBehalfOfContentOwnerChannel parameter value
// specifies must be linked to the content owner that the
// onBehalfOfContentOwner parameter specifies. This parameter is
// intended for YouTube content partners that own and manage many
// different YouTube channels. It allows content owners to authenticate
// once and perform actions on behalf of the channel specified in the
// parameter value, without having to provide authentication credentials
// for each separate channel.
func (c *LiveStreamsDeleteCall) OnBehalfOfContentOwnerChannel(onBehalfOfContentOwnerChannel string) *LiveStreamsDeleteCall {
	c.urlParams_.Set("onBehalfOfContentOwnerChannel", onBehalfOfContentOwnerChannel)
	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 *LiveStreamsDeleteCall) Fields(s ...googleapi.Field) *LiveStreamsDeleteCall {
	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 *LiveStreamsDeleteCall) Context(ctx context.Context) *LiveStreamsDeleteCall {
	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 *LiveStreamsDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

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

// Do executes the "youtube.liveStreams.delete" call.
func (c *LiveStreamsDeleteCall) Do(opts ...googleapi.CallOption) error {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if err != nil {
		return err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return err
	}
	return nil
	// {
	//   "description": "Deletes an existing stream for the authenticated user.",
	//   "flatPath": "youtube/v3/liveStreams",
	//   "httpMethod": "DELETE",
	//   "id": "youtube.liveStreams.delete",
	//   "parameterOrder": [
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "location": "query",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "onBehalfOfContentOwner": {
	//       "description": "*Note:* This parameter is intended exclusively for YouTube content partners. The *onBehalfOfContentOwner* parameter indicates that the request's authorization credentials identify a YouTube CMS user who is acting on behalf of the content owner specified in the parameter value. This parameter is intended for YouTube content partners that own and manage many different YouTube channels. It allows content owners to authenticate once and get access to all their video and channel data, without having to provide authentication credentials for each individual channel. The CMS account that the user authenticates with must be linked to the specified YouTube content owner.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "onBehalfOfContentOwnerChannel": {
	//       "description": "This parameter can only be used in a properly authorized request. *Note:* This parameter is intended exclusively for YouTube content partners. The *onBehalfOfContentOwnerChannel* parameter specifies the YouTube channel ID of the channel to which a video is being added. This parameter is required when a request specifies a value for the onBehalfOfContentOwner parameter, and it can only be used in conjunction with that parameter. In addition, the request must be authorized using a CMS account that is linked to the content owner that the onBehalfOfContentOwner parameter specifies. Finally, the channel that the onBehalfOfContentOwnerChannel parameter value specifies must be linked to the content owner that the onBehalfOfContentOwner parameter specifies. This parameter is intended for YouTube content partners that own and manage many different YouTube channels. It allows content owners to authenticate once and perform actions on behalf of the channel specified in the parameter value, without having to provide authentication credentials for each separate channel.",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "youtube/v3/liveStreams",
	//   "scopes": [
	//     "https://www.googleapis.com/auth/youtube",
	//     "https://www.googleapis.com/auth/youtube.force-ssl"
	//   ]
	// }

}

// method id "youtube.liveStreams.insert":

type LiveStreamsInsertCall struct {
	s          *Service
	livestream *LiveStream
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Insert: Inserts a new stream for the authenticated user.
func (r *LiveStreamsService) Insert(part []string, livestream *LiveStream) *LiveStreamsInsertCall {
	c := &LiveStreamsInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.urlParams_.SetMulti("part", append([]string{}, part...))
	c.livestream = livestream
	return c
}

// OnBehalfOfContentOwner sets the optional parameter
// "onBehalfOfContentOwner": *Note:* This parameter is intended
// exclusively for YouTube content partners. The
// *onBehalfOfContentOwner* parameter indicates that the request's
// authorization credentials identify a YouTube CMS user who is acting
// on behalf of the content owner specified in the parameter value. This
// parameter is intended for YouTube content partners that own and
// manage many different YouTube channels. It allows content owners to
// authenticate once and get access to all their video and channel data,
// without having to provide authentication credentials for each
// individual channel. The CMS account that the user authenticates with
// must be linked to the specified YouTube content owner.
func (c *LiveStreamsInsertCall) OnBehalfOfContentOwner(onBehalfOfContentOwner string) *LiveStreamsInsertCall {
	c.urlParams_.Set("onBehalfOfContentOwner", onBehalfOfContentOwner)
	return c
}

// OnBehalfOfContentOwnerChannel sets the optional parameter
// "onBehalfOfContentOwnerChannel": This parameter can only be used in a
// properly authorized request. *Note:* This parameter is intended
// exclusively for YouTube content partners. The
// *onBehalfOfContentOwnerChannel* parameter specifies the YouTube
// channel ID of the channel to which a video is being added. This
// parameter is required when a request specifies a value for the
// onBehalfOfContentOwner parameter, and it can only be used in
// conjunction with that parameter. In addition, the request must be
// authorized using a CMS account that is linked to the content owner
// that the onBehalfOfContentOwner parameter specifies. Finally, the
// channel that the onBehalfOfContentOwnerChannel parameter value
// specifies must be linked to the content owner that the
// onBehalfOfContentOwner parameter specifies. This parameter is
// intended for YouTube content partners that own and manage many
// different YouTube channels. It allows content owners to authenticate
// once and perform actions on behalf of the channel specified in the
// parameter value, without having to provide authentication credentials
// for each separate channel.
func (c *LiveStreamsInsertCall) OnBehalfOfContentOwnerChannel(onBehalfOfContentOwnerChannel string) *LiveStreamsInsertCall {
	c.urlParams_.Set("onBehalfOfContentOwnerChannel", onBehalfOfContentOwnerChannel)
	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 *LiveStreamsInsertCall) Fields(s ...googleapi.Field) *LiveStreamsInsertCall {
	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 *LiveStreamsInsertCall) Context(ctx context.Context) *LiveStreamsInsertCall {
	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 *LiveStreamsInsertCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *LiveStreamsInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200912")
	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.livestream)
	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, "youtube/v3/liveStreams")
	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 "youtube.liveStreams.insert" call.
// Exactly one of *LiveStream or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *LiveStream.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 *LiveStreamsInsertCall) Do(opts ...googleapi.CallOption) (*LiveStream, 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 := &LiveStream{
		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": "Inserts a new stream for the authenticated user.",
	//   "flatPath": "youtube/v3/liveStreams",
	//   "httpMethod": "POST",
	//   "id": "youtube.liveStreams.insert",
	//   "parameterOrder": [
	//     "part"
	//   ],
	//   "parameters": {
	//     "onBehalfOfContentOwner": {
	//       "description": "*Note:* This parameter is intended exclusively for YouTube content partners. The *onBehalfOfContentOwner* parameter indicates that the request's authorization credentials identify a YouTube CMS user who is acting on behalf of the content owner specified in the parameter value. This parameter is intended for YouTube content partners that own and manage many different YouTube channels. It allows content owners to authenticate once and get access to all their video and channel data, without having to provide authentication credentials for each individual channel. The CMS account that the user authenticates with must be linked to the specified YouTube content owner.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "onBehalfOfContentOwnerChannel": {
	//       "description": "This parameter can only be used in a properly authorized request. *Note:* This parameter is intended exclusively for YouTube content partners. The *onBehalfOfContentOwnerChannel* parameter specifies the YouTube channel ID of the channel to which a video is being added. This parameter is required when a request specifies a value for the onBehalfOfContentOwner parameter, and it can only be used in conjunction with that parameter. In addition, the request must be authorized using a CMS account that is linked to the content owner that the onBehalfOfContentOwner parameter specifies. Finally, the channel that the onBehalfOfContentOwnerChannel parameter value specifies must be linked to the content owner that the onBehalfOfContentOwner parameter specifies. This parameter is intended for YouTube content partners that own and manage many different YouTube channels. It allows content owners to authenticate once and perform actions on behalf of the channel specified in the parameter value, without having to provide authentication credentials for each separate channel.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "part": {
	//       "description": "The *part* parameter serves two purposes in this operation. It identifies the properties that the write operation will set as well as the properties that the API response will include. The part properties that you can include in the parameter value are id, snippet, cdn, and status.",
	//       "location": "query",
	//       "repeated": true,
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "youtube/v3/liveStreams",
	//   "request": {
	//     "$ref": "LiveStream"
	//   },
	//   "response": {
	//     "$ref": "LiveStream"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/youtube",
	//     "https://www.googleapis.com/auth/youtube.force-ssl"
	//   ]
	// }

}

// method id "youtube.liveStreams.list":

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

// List: Retrieve the list of streams associated with the given channel.
// --
func (r *LiveStreamsService) List(part []string) *LiveStreamsListCall {
	c := &LiveStreamsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.urlParams_.SetMulti("part", append([]string{}, part...))
	return c
}

// Id sets the optional parameter "id": Return LiveStreams with the
// given ids from Stubby or Apiary.
func (c *LiveStreamsListCall) Id(id ...string) *LiveStreamsListCall {
	c.urlParams_.SetMulti("id", append([]string{}, id...))
	return c
}

// MaxResults sets the optional parameter "maxResults": The *maxResults*
// parameter specifies the maximum number of items that should be
// returned in the result set.
func (c *LiveStreamsListCall) MaxResults(maxResults int64) *LiveStreamsListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// Mine sets the optional parameter "mine":
func (c *LiveStreamsListCall) Mine(mine bool) *LiveStreamsListCall {
	c.urlParams_.Set("mine", fmt.Sprint(mine))
	return c
}

// OnBehalfOfContentOwner sets the optional parameter
// "onBehalfOfContentOwner": *Note:* This parameter is intended
// exclusively for YouTube content partners. The
// *onBehalfOfContentOwner* parameter indicates that the request's
// authorization credentials identify a YouTube CMS user who is acting
// on behalf of the content owner specified in the parameter value. This
// parameter is intended for YouTube content partners that own and
// manage many different YouTube channels. It allows content owners to
// authenticate once and get access to all their video and channel data,
// without having to provide authentication credentials for each
// individual channel. The CMS account that the user authenticates with
// must be linked to the specified YouTube content owner.
func (c *LiveStreamsListCall) OnBehalfOfContentOwner(onBehalfOfContentOwner string) *LiveStreamsListCall {
	c.urlParams_.Set("onBehalfOfContentOwner", onBehalfOfContentOwner)
	return c
}

// OnBehalfOfContentOwnerChannel sets the optional parameter
// "onBehalfOfContentOwnerChannel": This parameter can only be used in a
// properly authorized request. *Note:* This parameter is intended
// exclusively for YouTube content partners. The
// *onBehalfOfContentOwnerChannel* parameter specifies the YouTube
// channel ID of the channel to which a video is being added. This
// parameter is required when a request specifies a value for the
// onBehalfOfContentOwner parameter, and it can only be used in
// conjunction with that parameter. In addition, the request must be
// authorized using a CMS account that is linked to the content owner
// that the onBehalfOfContentOwner parameter specifies. Finally, the
// channel that the onBehalfOfContentOwnerChannel parameter value
// specifies must be linked to the content owner that the
// onBehalfOfContentOwner parameter specifies. This parameter is
// intended for YouTube content partners that own and manage many
// different YouTube channels. It allows content owners to authenticate
// once and perform actions on behalf of the channel specified in the
// parameter value, without having to provide authentication credentials
// for each separate channel.
func (c *LiveStreamsListCall) OnBehalfOfContentOwnerChannel(onBehalfOfContentOwnerChannel string) *LiveStreamsListCall {
	c.urlParams_.Set("onBehalfOfContentOwnerChannel", onBehalfOfContentOwnerChannel)
	return c
}

// PageToken sets the optional parameter "pageToken": The *pageToken*
// parameter identifies a specific page in the result set that should be
// returned. In an API response, the nextPageToken and prevPageToken
// properties identify other pages that could be retrieved.
func (c *LiveStreamsListCall) PageToken(pageToken string) *LiveStreamsListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

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

func (c *LiveStreamsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200912")
	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, "youtube/v3/liveStreams")
	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 "youtube.liveStreams.list" call.
// Exactly one of *LiveStreamListResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *LiveStreamListResponse.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 *LiveStreamsListCall) Do(opts ...googleapi.CallOption) (*LiveStreamListResponse, 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 := &LiveStreamListResponse{
		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": "Retrieve the list of streams associated with the given channel. --",
	//   "flatPath": "youtube/v3/liveStreams",
	//   "httpMethod": "GET",
	//   "id": "youtube.liveStreams.list",
	//   "parameterOrder": [
	//     "part"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "Return LiveStreams with the given ids from Stubby or Apiary.",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "5",
	//       "description": "The *maxResults* parameter specifies the maximum number of items that should be returned in the result set.",
	//       "format": "uint32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "mine": {
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "onBehalfOfContentOwner": {
	//       "description": "*Note:* This parameter is intended exclusively for YouTube content partners. The *onBehalfOfContentOwner* parameter indicates that the request's authorization credentials identify a YouTube CMS user who is acting on behalf of the content owner specified in the parameter value. This parameter is intended for YouTube content partners that own and manage many different YouTube channels. It allows content owners to authenticate once and get access to all their video and channel data, without having to provide authentication credentials for each individual channel. The CMS account that the user authenticates with must be linked to the specified YouTube content owner.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "onBehalfOfContentOwnerChannel": {
	//       "description": "This parameter can only be used in a properly authorized request. *Note:* This parameter is intended exclusively for YouTube content partners. The *onBehalfOfContentOwnerChannel* parameter specifies the YouTube channel ID of the channel to which a video is being added. This parameter is required when a request specifies a value for the onBehalfOfContentOwner parameter, and it can only be used in conjunction with that parameter. In addition, the request must be authorized using a CMS account that is linked to the content owner that the onBehalfOfContentOwner parameter specifies. Finally, the channel that the onBehalfOfContentOwnerChannel parameter value specifies must be linked to the content owner that the onBehalfOfContentOwner parameter specifies. This parameter is intended for YouTube content partners that own and manage many different YouTube channels. It allows content owners to authenticate once and perform actions on behalf of the channel specified in the parameter value, without having to provide authentication credentials for each separate channel.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageToken": {
	//       "description": "The *pageToken* parameter identifies a specific page in the result set that should be returned. In an API response, the nextPageToken and prevPageToken properties identify other pages that could be retrieved.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "part": {
	//       "description": "The *part* parameter specifies a comma-separated list of one or more liveStream resource properties that the API response will include. The part names that you can include in the parameter value are id, snippet, cdn, and status.",
	//       "location": "query",
	//       "repeated": true,
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "youtube/v3/liveStreams",
	//   "response": {
	//     "$ref": "LiveStreamListResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/youtube",
	//     "https://www.googleapis.com/auth/youtube.force-ssl",
	//     "https://www.googleapis.com/auth/youtube.readonly"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *LiveStreamsListCall) Pages(ctx context.Context, f func(*LiveStreamListResponse) 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 "youtube.liveStreams.update":

type LiveStreamsUpdateCall struct {
	s          *Service
	livestream *LiveStream
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Update: Updates an existing stream for the authenticated user.
func (r *LiveStreamsService) Update(part []string, livestream *LiveStream) *LiveStreamsUpdateCall {
	c := &LiveStreamsUpdateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.urlParams_.SetMulti("part", append([]string{}, part...))
	c.livestream = livestream
	return c
}

// OnBehalfOfContentOwner sets the optional parameter
// "onBehalfOfContentOwner": *Note:* This parameter is intended
// exclusively for YouTube content partners. The
// *onBehalfOfContentOwner* parameter indicates that the request's
// authorization credentials identify a YouTube CMS user who is acting
// on behalf of the content owner specified in the parameter value. This
// parameter is intended for YouTube content partners that own and
// manage many different YouTube channels. It allows content owners to
// authenticate once and get access to all their video and channel data,
// without having to provide authentication credentials for each
// individual channel. The CMS account that the user authenticates with
// must be linked to the specified YouTube content owner.
func (c *LiveStreamsUpdateCall) OnBehalfOfContentOwner(onBehalfOfContentOwner string) *LiveStreamsUpdateCall {
	c.urlParams_.Set("onBehalfOfContentOwner", onBehalfOfContentOwner)
	return c
}

// OnBehalfOfContentOwnerChannel sets the optional parameter
// "onBehalfOfContentOwnerChannel": This parameter can only be used in a
// properly authorized request. *Note:* This parameter is intended
// exclusively for YouTube content partners. The
// *onBehalfOfContentOwnerChannel* parameter specifies the YouTube
// channel ID of the channel to which a video is being added. This
// parameter is required when a request specifies a value for the
// onBehalfOfContentOwner parameter, and it can only be used in
// conjunction with that parameter. In addition, the request must be
// authorized using a CMS account that is linked to the content owner
// that the onBehalfOfContentOwner parameter specifies. Finally, the
// channel that the onBehalfOfContentOwnerChannel parameter value
// specifies must be linked to the content owner that the
// onBehalfOfContentOwner parameter specifies. This parameter is
// intended for YouTube content partners that own and manage many
// different YouTube channels. It allows content owners to authenticate
// once and perform actions on behalf of the channel specified in the
// parameter value, without having to provide authentication credentials
// for each separate channel.
func (c *LiveStreamsUpdateCall) OnBehalfOfContentOwnerChannel(onBehalfOfContentOwnerChannel string) *LiveStreamsUpdateCall {
	c.urlParams_.Set("onBehalfOfContentOwnerChannel", onBehalfOfContentOwnerChannel)
	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 *LiveStreamsUpdateCall) Fields(s ...googleapi.Field) *LiveStreamsUpdateCall {
	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 *LiveStreamsUpdateCall) Context(ctx context.Context) *LiveStreamsUpdateCall {
	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 *LiveStreamsUpdateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

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

// Do executes the "youtube.liveStreams.update" call.
// Exactly one of *LiveStream or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *LiveStream.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 *LiveStreamsUpdateCall) Do(opts ...googleapi.CallOption) (*LiveStream, 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 := &LiveStream{
		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 existing stream for the authenticated user.",
	//   "flatPath": "youtube/v3/liveStreams",
	//   "httpMethod": "PUT",
	//   "id": "youtube.liveStreams.update",
	//   "parameterOrder": [
	//     "part"
	//   ],
	//   "parameters": {
	//     "onBehalfOfContentOwner": {
	//       "description": "*Note:* This parameter is intended exclusively for YouTube content partners. The *onBehalfOfContentOwner* parameter indicates that the request's authorization credentials identify a YouTube CMS user who is acting on behalf of the content owner specified in the parameter value. This parameter is intended for YouTube content partners that own and manage many different YouTube channels. It allows content owners to authenticate once and get access to all their video and channel data, without having to provide authentication credentials for each individual channel. The CMS account that the user authenticates with must be linked to the specified YouTube content owner.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "onBehalfOfContentOwnerChannel": {
	//       "description": "This parameter can only be used in a properly authorized request. *Note:* This parameter is intended exclusively for YouTube content partners. The *onBehalfOfContentOwnerChannel* parameter specifies the YouTube channel ID of the channel to which a video is being added. This parameter is required when a request specifies a value for the onBehalfOfContentOwner parameter, and it can only be used in conjunction with that parameter. In addition, the request must be authorized using a CMS account that is linked to the content owner that the onBehalfOfContentOwner parameter specifies. Finally, the channel that the onBehalfOfContentOwnerChannel parameter value specifies must be linked to the content owner that the onBehalfOfContentOwner parameter specifies. This parameter is intended for YouTube content partners that own and manage many different YouTube channels. It allows content owners to authenticate once and perform actions on behalf of the channel specified in the parameter value, without having to provide authentication credentials for each separate channel.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "part": {
	//       "description": "The *part* parameter serves two purposes in this operation. It identifies the properties that the write operation will set as well as the properties that the API response will include. The part properties that you can include in the parameter value are id, snippet, cdn, and status. Note that this method will override the existing values for all of the mutable properties that are contained in any parts that the parameter value specifies. If the request body does not specify a value for a mutable property, the existing value for that property will be removed.",
	//       "location": "query",
	//       "repeated": true,
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "youtube/v3/liveStreams",
	//   "request": {
	//     "$ref": "LiveStream"
	//   },
	//   "response": {
	//     "$ref": "LiveStream"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/youtube",
	//     "https://www.googleapis.com/auth/youtube.force-ssl"
	//   ]
	// }

}

// method id "youtube.members.list":

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

// List: Retrieves a list of members that match the request criteria for
// a channel.
func (r *MembersService) List(part []string) *MembersListCall {
	c := &MembersListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.urlParams_.SetMulti("part", append([]string{}, part...))
	return c
}

// FilterByMemberChannelId sets the optional parameter
// "filterByMemberChannelId": Comma separated list of channel IDs. Only
// data about members that are part of this list will be included in the
// response.
func (c *MembersListCall) FilterByMemberChannelId(filterByMemberChannelId string) *MembersListCall {
	c.urlParams_.Set("filterByMemberChannelId", filterByMemberChannelId)
	return c
}

// HasAccessToLevel sets the optional parameter "hasAccessToLevel":
// Filter members in the results set to the ones that have access to a
// level.
func (c *MembersListCall) HasAccessToLevel(hasAccessToLevel string) *MembersListCall {
	c.urlParams_.Set("hasAccessToLevel", hasAccessToLevel)
	return c
}

// MaxResults sets the optional parameter "maxResults": The *maxResults*
// parameter specifies the maximum number of items that should be
// returned in the result set.
func (c *MembersListCall) MaxResults(maxResults int64) *MembersListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// Mode sets the optional parameter "mode": Parameter that specifies
// which channel members to return.
//
// Possible values:
//   "listMembersModeUnknown"
//   "updates"
//   "all_current" (default)
func (c *MembersListCall) Mode(mode string) *MembersListCall {
	c.urlParams_.Set("mode", mode)
	return c
}

// PageToken sets the optional parameter "pageToken": The *pageToken*
// parameter identifies a specific page in the result set that should be
// returned. In an API response, the nextPageToken and prevPageToken
// properties identify other pages that could be retrieved.
func (c *MembersListCall) PageToken(pageToken string) *MembersListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

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

func (c *MembersListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200912")
	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, "youtube/v3/members")
	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 "youtube.members.list" call.
// Exactly one of *MemberListResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *MemberListResponse.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 *MembersListCall) Do(opts ...googleapi.CallOption) (*MemberListResponse, 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 := &MemberListResponse{
		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": "Retrieves a list of members that match the request criteria for a channel.",
	//   "flatPath": "youtube/v3/members",
	//   "httpMethod": "GET",
	//   "id": "youtube.members.list",
	//   "parameterOrder": [
	//     "part"
	//   ],
	//   "parameters": {
	//     "filterByMemberChannelId": {
	//       "description": "Comma separated list of channel IDs. Only data about members that are part of this list will be included in the response.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "hasAccessToLevel": {
	//       "description": "Filter members in the results set to the ones that have access to a level.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "5",
	//       "description": "The *maxResults* parameter specifies the maximum number of items that should be returned in the result set.",
	//       "format": "uint32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "mode": {
	//       "default": "all_current",
	//       "description": "Parameter that specifies which channel members to return.",
	//       "enum": [
	//         "listMembersModeUnknown",
	//         "updates",
	//         "all_current"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageToken": {
	//       "description": "The *pageToken* parameter identifies a specific page in the result set that should be returned. In an API response, the nextPageToken and prevPageToken properties identify other pages that could be retrieved.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "part": {
	//       "description": "The *part* parameter specifies the member resource parts that the API response will include. Set the parameter value to snippet.",
	//       "location": "query",
	//       "repeated": true,
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "youtube/v3/members",
	//   "response": {
	//     "$ref": "MemberListResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/youtube",
	//     "https://www.googleapis.com/auth/youtube.channel-memberships.creator",
	//     "https://www.googleapis.com/auth/youtube.force-ssl",
	//     "https://www.googleapis.com/auth/youtube.readonly",
	//     "https://www.googleapis.com/auth/youtubepartner"
	//   ]
	// }

}

// 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 *MembersListCall) Pages(ctx context.Context, f func(*MemberListResponse) 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 "youtube.membershipsLevels.list":

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

// List: Retrieves a list of all pricing levels offered by a creator to
// the fans.
func (r *MembershipsLevelsService) List(part []string) *MembershipsLevelsListCall {
	c := &MembershipsLevelsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.urlParams_.SetMulti("part", append([]string{}, part...))
	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 *MembershipsLevelsListCall) Fields(s ...googleapi.Field) *MembershipsLevelsListCall {
	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 *MembershipsLevelsListCall) IfNoneMatch(entityTag string) *MembershipsLevelsListCall {
	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 *MembershipsLevelsListCall) Context(ctx context.Context) *MembershipsLevelsListCall {
	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 *MembershipsLevelsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *MembershipsLevelsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200912")
	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, "youtube/v3/membershipsLevels")
	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 "youtube.membershipsLevels.list" call.
// Exactly one of *MembershipsLevelListResponse or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *MembershipsLevelListResponse.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 *MembershipsLevelsListCall) Do(opts ...googleapi.CallOption) (*MembershipsLevelListResponse, 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 := &MembershipsLevelListResponse{
		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": "Retrieves a list of all pricing levels offered by a creator to the fans.",
	//   "flatPath": "youtube/v3/membershipsLevels",
	//   "httpMethod": "GET",
	//   "id": "youtube.membershipsLevels.list",
	//   "parameterOrder": [
	//     "part"
	//   ],
	//   "parameters": {
	//     "part": {
	//       "description": "The *part* parameter specifies the membershipsLevel resource parts that the API response will include. Supported values are id and snippet.",
	//       "location": "query",
	//       "repeated": true,
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "youtube/v3/membershipsLevels",
	//   "response": {
	//     "$ref": "MembershipsLevelListResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/youtube",
	//     "https://www.googleapis.com/auth/youtube.channel-memberships.creator",
	//     "https://www.googleapis.com/auth/youtube.force-ssl",
	//     "https://www.googleapis.com/auth/youtube.readonly",
	//     "https://www.googleapis.com/auth/youtubepartner"
	//   ]
	// }

}

// method id "youtube.playlistItems.delete":

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

// Delete: Deletes a resource.
func (r *PlaylistItemsService) Delete(id string) *PlaylistItemsDeleteCall {
	c := &PlaylistItemsDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.urlParams_.Set("id", id)
	return c
}

// OnBehalfOfContentOwner sets the optional parameter
// "onBehalfOfContentOwner": *Note:* This parameter is intended
// exclusively for YouTube content partners. The
// *onBehalfOfContentOwner* parameter indicates that the request's
// authorization credentials identify a YouTube CMS user who is acting
// on behalf of the content owner specified in the parameter value. This
// parameter is intended for YouTube content partners that own and
// manage many different YouTube channels. It allows content owners to
// authenticate once and get access to all their video and channel data,
// without having to provide authentication credentials for each
// individual channel. The CMS account that the user authenticates with
// must be linked to the specified YouTube content owner.
func (c *PlaylistItemsDeleteCall) OnBehalfOfContentOwner(onBehalfOfContentOwner string) *PlaylistItemsDeleteCall {
	c.urlParams_.Set("onBehalfOfContentOwner", onBehalfOfContentOwner)
	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 *PlaylistItemsDeleteCall) Fields(s ...googleapi.Field) *PlaylistItemsDeleteCall {
	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 *PlaylistItemsDeleteCall) Context(ctx context.Context) *PlaylistItemsDeleteCall {
	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 *PlaylistItemsDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

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

// Do executes the "youtube.playlistItems.delete" call.
func (c *PlaylistItemsDeleteCall) Do(opts ...googleapi.CallOption) error {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if err != nil {
		return err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return err
	}
	return nil
	// {
	//   "description": "Deletes a resource.",
	//   "flatPath": "youtube/v3/playlistItems",
	//   "httpMethod": "DELETE",
	//   "id": "youtube.playlistItems.delete",
	//   "parameterOrder": [
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "location": "query",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "onBehalfOfContentOwner": {
	//       "description": "*Note:* This parameter is intended exclusively for YouTube content partners. The *onBehalfOfContentOwner* parameter indicates that the request's authorization credentials identify a YouTube CMS user who is acting on behalf of the content owner specified in the parameter value. This parameter is intended for YouTube content partners that own and manage many different YouTube channels. It allows content owners to authenticate once and get access to all their video and channel data, without having to provide authentication credentials for each individual channel. The CMS account that the user authenticates with must be linked to the specified YouTube content owner.",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "youtube/v3/playlistItems",
	//   "scopes": [
	//     "https://www.googleapis.com/auth/youtube",
	//     "https://www.googleapis.com/auth/youtube.force-ssl",
	//     "https://www.googleapis.com/auth/youtubepartner"
	//   ]
	// }

}

// method id "youtube.playlistItems.insert":

type PlaylistItemsInsertCall struct {
	s            *Service
	playlistitem *PlaylistItem
	urlParams_   gensupport.URLParams
	ctx_         context.Context
	header_      http.Header
}

// Insert: Inserts a new resource into this collection.
func (r *PlaylistItemsService) Insert(part []string, playlistitem *PlaylistItem) *PlaylistItemsInsertCall {
	c := &PlaylistItemsInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.urlParams_.SetMulti("part", append([]string{}, part...))
	c.playlistitem = playlistitem
	return c
}

// OnBehalfOfContentOwner sets the optional parameter
// "onBehalfOfContentOwner": *Note:* This parameter is intended
// exclusively for YouTube content partners. The
// *onBehalfOfContentOwner* parameter indicates that the request's
// authorization credentials identify a YouTube CMS user who is acting
// on behalf of the content owner specified in the parameter value. This
// parameter is intended for YouTube content partners that own and
// manage many different YouTube channels. It allows content owners to
// authenticate once and get access to all their video and channel data,
// without having to provide authentication credentials for each
// individual channel. The CMS account that the user authenticates with
// must be linked to the specified YouTube content owner.
func (c *PlaylistItemsInsertCall) OnBehalfOfContentOwner(onBehalfOfContentOwner string) *PlaylistItemsInsertCall {
	c.urlParams_.Set("onBehalfOfContentOwner", onBehalfOfContentOwner)
	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 *PlaylistItemsInsertCall) Fields(s ...googleapi.Field) *PlaylistItemsInsertCall {
	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 *PlaylistItemsInsertCall) Context(ctx context.Context) *PlaylistItemsInsertCall {
	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 *PlaylistItemsInsertCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *PlaylistItemsInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200912")
	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.playlistitem)
	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, "youtube/v3/playlistItems")
	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 "youtube.playlistItems.insert" call.
// Exactly one of *PlaylistItem or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *PlaylistItem.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 *PlaylistItemsInsertCall) Do(opts ...googleapi.CallOption) (*PlaylistItem, 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 := &PlaylistItem{
		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": "Inserts a new resource into this collection.",
	//   "flatPath": "youtube/v3/playlistItems",
	//   "httpMethod": "POST",
	//   "id": "youtube.playlistItems.insert",
	//   "parameterOrder": [
	//     "part"
	//   ],
	//   "parameters": {
	//     "onBehalfOfContentOwner": {
	//       "description": "*Note:* This parameter is intended exclusively for YouTube content partners. The *onBehalfOfContentOwner* parameter indicates that the request's authorization credentials identify a YouTube CMS user who is acting on behalf of the content owner specified in the parameter value. This parameter is intended for YouTube content partners that own and manage many different YouTube channels. It allows content owners to authenticate once and get access to all their video and channel data, without having to provide authentication credentials for each individual channel. The CMS account that the user authenticates with must be linked to the specified YouTube content owner.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "part": {
	//       "description": "The *part* parameter serves two purposes in this operation. It identifies the properties that the write operation will set as well as the properties that the API response will include.",
	//       "location": "query",
	//       "repeated": true,
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "youtube/v3/playlistItems",
	//   "request": {
	//     "$ref": "PlaylistItem"
	//   },
	//   "response": {
	//     "$ref": "PlaylistItem"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/youtube",
	//     "https://www.googleapis.com/auth/youtube.force-ssl",
	//     "https://www.googleapis.com/auth/youtubepartner"
	//   ]
	// }

}

// method id "youtube.playlistItems.list":

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

// List: Retrieves a list of resources, possibly filtered.
func (r *PlaylistItemsService) List(part []string) *PlaylistItemsListCall {
	c := &PlaylistItemsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.urlParams_.SetMulti("part", append([]string{}, part...))
	return c
}

// Id sets the optional parameter "id":
func (c *PlaylistItemsListCall) Id(id ...string) *PlaylistItemsListCall {
	c.urlParams_.SetMulti("id", append([]string{}, id...))
	return c
}

// MaxResults sets the optional parameter "maxResults": The *maxResults*
// parameter specifies the maximum number of items that should be
// returned in the result set.
func (c *PlaylistItemsListCall) MaxResults(maxResults int64) *PlaylistItemsListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// OnBehalfOfContentOwner sets the optional parameter
// "onBehalfOfContentOwner": *Note:* This parameter is intended
// exclusively for YouTube content partners. The
// *onBehalfOfContentOwner* parameter indicates that the request's
// authorization credentials identify a YouTube CMS user who is acting
// on behalf of the content owner specified in the parameter value. This
// parameter is intended for YouTube content partners that own and
// manage many different YouTube channels. It allows content owners to
// authenticate once and get access to all their video and channel data,
// without having to provide authentication credentials for each
// individual channel. The CMS account that the user authenticates with
// must be linked to the specified YouTube content owner.
func (c *PlaylistItemsListCall) OnBehalfOfContentOwner(onBehalfOfContentOwner string) *PlaylistItemsListCall {
	c.urlParams_.Set("onBehalfOfContentOwner", onBehalfOfContentOwner)
	return c
}

// PageToken sets the optional parameter "pageToken": The *pageToken*
// parameter identifies a specific page in the result set that should be
// returned. In an API response, the nextPageToken and prevPageToken
// properties identify other pages that could be retrieved.
func (c *PlaylistItemsListCall) PageToken(pageToken string) *PlaylistItemsListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// PlaylistId sets the optional parameter "playlistId": Return the
// playlist items within the given playlist.
func (c *PlaylistItemsListCall) PlaylistId(playlistId string) *PlaylistItemsListCall {
	c.urlParams_.Set("playlistId", playlistId)
	return c
}

// VideoId sets the optional parameter "videoId": Return the playlist
// items associated with the given video ID.
func (c *PlaylistItemsListCall) VideoId(videoId string) *PlaylistItemsListCall {
	c.urlParams_.Set("videoId", videoId)
	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 *PlaylistItemsListCall) Fields(s ...googleapi.Field) *PlaylistItemsListCall {
	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 *PlaylistItemsListCall) IfNoneMatch(entityTag string) *PlaylistItemsListCall {
	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 *PlaylistItemsListCall) Context(ctx context.Context) *PlaylistItemsListCall {
	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 *PlaylistItemsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *PlaylistItemsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200912")
	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, "youtube/v3/playlistItems")
	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 "youtube.playlistItems.list" call.
// Exactly one of *PlaylistItemListResponse or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *PlaylistItemListResponse.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 *PlaylistItemsListCall) Do(opts ...googleapi.CallOption) (*PlaylistItemListResponse, 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 := &PlaylistItemListResponse{
		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": "Retrieves a list of resources, possibly filtered.",
	//   "flatPath": "youtube/v3/playlistItems",
	//   "httpMethod": "GET",
	//   "id": "youtube.playlistItems.list",
	//   "parameterOrder": [
	//     "part"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "5",
	//       "description": "The *maxResults* parameter specifies the maximum number of items that should be returned in the result set.",
	//       "format": "uint32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "onBehalfOfContentOwner": {
	//       "description": "*Note:* This parameter is intended exclusively for YouTube content partners. The *onBehalfOfContentOwner* parameter indicates that the request's authorization credentials identify a YouTube CMS user who is acting on behalf of the content owner specified in the parameter value. This parameter is intended for YouTube content partners that own and manage many different YouTube channels. It allows content owners to authenticate once and get access to all their video and channel data, without having to provide authentication credentials for each individual channel. The CMS account that the user authenticates with must be linked to the specified YouTube content owner.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageToken": {
	//       "description": "The *pageToken* parameter identifies a specific page in the result set that should be returned. In an API response, the nextPageToken and prevPageToken properties identify other pages that could be retrieved.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "part": {
	//       "description": "The *part* parameter specifies a comma-separated list of one or more playlistItem resource properties that the API response will include. If the parameter identifies a property that contains child properties, the child properties will be included in the response. For example, in a playlistItem resource, the snippet property contains numerous fields, including the title, description, position, and resourceId properties. As such, if you set *part=snippet*, the API response will contain all of those properties.",
	//       "location": "query",
	//       "repeated": true,
	//       "required": true,
	//       "type": "string"
	//     },
	//     "playlistId": {
	//       "description": "Return the playlist items within the given playlist.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "videoId": {
	//       "description": "Return the playlist items associated with the given video ID.",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "youtube/v3/playlistItems",
	//   "response": {
	//     "$ref": "PlaylistItemListResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/youtube",
	//     "https://www.googleapis.com/auth/youtube.force-ssl",
	//     "https://www.googleapis.com/auth/youtube.readonly",
	//     "https://www.googleapis.com/auth/youtubepartner"
	//   ]
	// }

}

// 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 *PlaylistItemsListCall) Pages(ctx context.Context, f func(*PlaylistItemListResponse) 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 "youtube.playlistItems.update":

type PlaylistItemsUpdateCall struct {
	s            *Service
	playlistitem *PlaylistItem
	urlParams_   gensupport.URLParams
	ctx_         context.Context
	header_      http.Header
}

// Update: Updates an existing resource.
func (r *PlaylistItemsService) Update(part []string, playlistitem *PlaylistItem) *PlaylistItemsUpdateCall {
	c := &PlaylistItemsUpdateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.urlParams_.SetMulti("part", append([]string{}, part...))
	c.playlistitem = playlistitem
	return c
}

// OnBehalfOfContentOwner sets the optional parameter
// "onBehalfOfContentOwner": *Note:* This parameter is intended
// exclusively for YouTube content partners. The
// *onBehalfOfContentOwner* parameter indicates that the request's
// authorization credentials identify a YouTube CMS user who is acting
// on behalf of the content owner specified in the parameter value. This
// parameter is intended for YouTube content partners that own and
// manage many different YouTube channels. It allows content owners to
// authenticate once and get access to all their video and channel data,
// without having to provide authentication credentials for each
// individual channel. The CMS account that the user authenticates with
// must be linked to the specified YouTube content owner.
func (c *PlaylistItemsUpdateCall) OnBehalfOfContentOwner(onBehalfOfContentOwner string) *PlaylistItemsUpdateCall {
	c.urlParams_.Set("onBehalfOfContentOwner", onBehalfOfContentOwner)
	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 *PlaylistItemsUpdateCall) Fields(s ...googleapi.Field) *PlaylistItemsUpdateCall {
	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 *PlaylistItemsUpdateCall) Context(ctx context.Context) *PlaylistItemsUpdateCall {
	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 *PlaylistItemsUpdateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

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

// Do executes the "youtube.playlistItems.update" call.
// Exactly one of *PlaylistItem or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *PlaylistItem.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 *PlaylistItemsUpdateCall) Do(opts ...googleapi.CallOption) (*PlaylistItem, 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 := &PlaylistItem{
		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 existing resource.",
	//   "flatPath": "youtube/v3/playlistItems",
	//   "httpMethod": "PUT",
	//   "id": "youtube.playlistItems.update",
	//   "parameterOrder": [
	//     "part"
	//   ],
	//   "parameters": {
	//     "onBehalfOfContentOwner": {
	//       "description": "*Note:* This parameter is intended exclusively for YouTube content partners. The *onBehalfOfContentOwner* parameter indicates that the request's authorization credentials identify a YouTube CMS user who is acting on behalf of the content owner specified in the parameter value. This parameter is intended for YouTube content partners that own and manage many different YouTube channels. It allows content owners to authenticate once and get access to all their video and channel data, without having to provide authentication credentials for each individual channel. The CMS account that the user authenticates with must be linked to the specified YouTube content owner.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "part": {
	//       "description": "The *part* parameter serves two purposes in this operation. It identifies the properties that the write operation will set as well as the properties that the API response will include. Note that this method will override the existing values for all of the mutable properties that are contained in any parts that the parameter value specifies. For example, a playlist item can specify a start time and end time, which identify the times portion of the video that should play when users watch the video in the playlist. If your request is updating a playlist item that sets these values, and the request's part parameter value includes the contentDetails part, the playlist item's start and end times will be updated to whatever value the request body specifies. If the request body does not specify values, the existing start and end times will be removed and replaced with the default settings.",
	//       "location": "query",
	//       "repeated": true,
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "youtube/v3/playlistItems",
	//   "request": {
	//     "$ref": "PlaylistItem"
	//   },
	//   "response": {
	//     "$ref": "PlaylistItem"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/youtube",
	//     "https://www.googleapis.com/auth/youtube.force-ssl",
	//     "https://www.googleapis.com/auth/youtubepartner"
	//   ]
	// }

}

// method id "youtube.playlists.delete":

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

// Delete: Deletes a resource.
func (r *PlaylistsService) Delete(id string) *PlaylistsDeleteCall {
	c := &PlaylistsDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.urlParams_.Set("id", id)
	return c
}

// OnBehalfOfContentOwner sets the optional parameter
// "onBehalfOfContentOwner": *Note:* This parameter is intended
// exclusively for YouTube content partners. The
// *onBehalfOfContentOwner* parameter indicates that the request's
// authorization credentials identify a YouTube CMS user who is acting
// on behalf of the content owner specified in the parameter value. This
// parameter is intended for YouTube content partners that own and
// manage many different YouTube channels. It allows content owners to
// authenticate once and get access to all their video and channel data,
// without having to provide authentication credentials for each
// individual channel. The CMS account that the user authenticates with
// must be linked to the specified YouTube content owner.
func (c *PlaylistsDeleteCall) OnBehalfOfContentOwner(onBehalfOfContentOwner string) *PlaylistsDeleteCall {
	c.urlParams_.Set("onBehalfOfContentOwner", onBehalfOfContentOwner)
	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 *PlaylistsDeleteCall) Fields(s ...googleapi.Field) *PlaylistsDeleteCall {
	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 *PlaylistsDeleteCall) Context(ctx context.Context) *PlaylistsDeleteCall {
	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 *PlaylistsDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

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

// Do executes the "youtube.playlists.delete" call.
func (c *PlaylistsDeleteCall) Do(opts ...googleapi.CallOption) error {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if err != nil {
		return err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return err
	}
	return nil
	// {
	//   "description": "Deletes a resource.",
	//   "flatPath": "youtube/v3/playlists",
	//   "httpMethod": "DELETE",
	//   "id": "youtube.playlists.delete",
	//   "parameterOrder": [
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "location": "query",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "onBehalfOfContentOwner": {
	//       "description": "*Note:* This parameter is intended exclusively for YouTube content partners. The *onBehalfOfContentOwner* parameter indicates that the request's authorization credentials identify a YouTube CMS user who is acting on behalf of the content owner specified in the parameter value. This parameter is intended for YouTube content partners that own and manage many different YouTube channels. It allows content owners to authenticate once and get access to all their video and channel data, without having to provide authentication credentials for each individual channel. The CMS account that the user authenticates with must be linked to the specified YouTube content owner.",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "youtube/v3/playlists",
	//   "scopes": [
	//     "https://www.googleapis.com/auth/youtube",
	//     "https://www.googleapis.com/auth/youtube.force-ssl",
	//     "https://www.googleapis.com/auth/youtubepartner"
	//   ]
	// }

}

// method id "youtube.playlists.insert":

type PlaylistsInsertCall struct {
	s          *Service
	playlist   *Playlist
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Insert: Inserts a new resource into this collection.
func (r *PlaylistsService) Insert(part []string, playlist *Playlist) *PlaylistsInsertCall {
	c := &PlaylistsInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.urlParams_.SetMulti("part", append([]string{}, part...))
	c.playlist = playlist
	return c
}

// OnBehalfOfContentOwner sets the optional parameter
// "onBehalfOfContentOwner": *Note:* This parameter is intended
// exclusively for YouTube content partners. The
// *onBehalfOfContentOwner* parameter indicates that the request's
// authorization credentials identify a YouTube CMS user who is acting
// on behalf of the content owner specified in the parameter value. This
// parameter is intended for YouTube content partners that own and
// manage many different YouTube channels. It allows content owners to
// authenticate once and get access to all their video and channel data,
// without having to provide authentication credentials for each
// individual channel. The CMS account that the user authenticates with
// must be linked to the specified YouTube content owner.
func (c *PlaylistsInsertCall) OnBehalfOfContentOwner(onBehalfOfContentOwner string) *PlaylistsInsertCall {
	c.urlParams_.Set("onBehalfOfContentOwner", onBehalfOfContentOwner)
	return c
}

// OnBehalfOfContentOwnerChannel sets the optional parameter
// "onBehalfOfContentOwnerChannel": This parameter can only be used in a
// properly authorized request. *Note:* This parameter is intended
// exclusively for YouTube content partners. The
// *onBehalfOfContentOwnerChannel* parameter specifies the YouTube
// channel ID of the channel to which a video is being added. This
// parameter is required when a request specifies a value for the
// onBehalfOfContentOwner parameter, and it can only be used in
// conjunction with that parameter. In addition, the request must be
// authorized using a CMS account that is linked to the content owner
// that the onBehalfOfContentOwner parameter specifies. Finally, the
// channel that the onBehalfOfContentOwnerChannel parameter value
// specifies must be linked to the content owner that the
// onBehalfOfContentOwner parameter specifies. This parameter is
// intended for YouTube content partners that own and manage many
// different YouTube channels. It allows content owners to authenticate
// once and perform actions on behalf of the channel specified in the
// parameter value, without having to provide authentication credentials
// for each separate channel.
func (c *PlaylistsInsertCall) OnBehalfOfContentOwnerChannel(onBehalfOfContentOwnerChannel string) *PlaylistsInsertCall {
	c.urlParams_.Set("onBehalfOfContentOwnerChannel", onBehalfOfContentOwnerChannel)
	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 *PlaylistsInsertCall) Fields(s ...googleapi.Field) *PlaylistsInsertCall {
	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 *PlaylistsInsertCall) Context(ctx context.Context) *PlaylistsInsertCall {
	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 *PlaylistsInsertCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *PlaylistsInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200912")
	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.playlist)
	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, "youtube/v3/playlists")
	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 "youtube.playlists.insert" call.
// Exactly one of *Playlist or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Playlist.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 *PlaylistsInsertCall) Do(opts ...googleapi.CallOption) (*Playlist, 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 := &Playlist{
		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": "Inserts a new resource into this collection.",
	//   "flatPath": "youtube/v3/playlists",
	//   "httpMethod": "POST",
	//   "id": "youtube.playlists.insert",
	//   "parameterOrder": [
	//     "part"
	//   ],
	//   "parameters": {
	//     "onBehalfOfContentOwner": {
	//       "description": "*Note:* This parameter is intended exclusively for YouTube content partners. The *onBehalfOfContentOwner* parameter indicates that the request's authorization credentials identify a YouTube CMS user who is acting on behalf of the content owner specified in the parameter value. This parameter is intended for YouTube content partners that own and manage many different YouTube channels. It allows content owners to authenticate once and get access to all their video and channel data, without having to provide authentication credentials for each individual channel. The CMS account that the user authenticates with must be linked to the specified YouTube content owner.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "onBehalfOfContentOwnerChannel": {
	//       "description": "This parameter can only be used in a properly authorized request. *Note:* This parameter is intended exclusively for YouTube content partners. The *onBehalfOfContentOwnerChannel* parameter specifies the YouTube channel ID of the channel to which a video is being added. This parameter is required when a request specifies a value for the onBehalfOfContentOwner parameter, and it can only be used in conjunction with that parameter. In addition, the request must be authorized using a CMS account that is linked to the content owner that the onBehalfOfContentOwner parameter specifies. Finally, the channel that the onBehalfOfContentOwnerChannel parameter value specifies must be linked to the content owner that the onBehalfOfContentOwner parameter specifies. This parameter is intended for YouTube content partners that own and manage many different YouTube channels. It allows content owners to authenticate once and perform actions on behalf of the channel specified in the parameter value, without having to provide authentication credentials for each separate channel.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "part": {
	//       "description": "The *part* parameter serves two purposes in this operation. It identifies the properties that the write operation will set as well as the properties that the API response will include.",
	//       "location": "query",
	//       "repeated": true,
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "youtube/v3/playlists",
	//   "request": {
	//     "$ref": "Playlist"
	//   },
	//   "response": {
	//     "$ref": "Playlist"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/youtube",
	//     "https://www.googleapis.com/auth/youtube.force-ssl",
	//     "https://www.googleapis.com/auth/youtubepartner"
	//   ]
	// }

}

// method id "youtube.playlists.list":

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

// List: Retrieves a list of resources, possibly filtered.
func (r *PlaylistsService) List(part []string) *PlaylistsListCall {
	c := &PlaylistsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.urlParams_.SetMulti("part", append([]string{}, part...))
	return c
}

// ChannelId sets the optional parameter "channelId": Return the
// playlists owned by the specified channel ID.
func (c *PlaylistsListCall) ChannelId(channelId string) *PlaylistsListCall {
	c.urlParams_.Set("channelId", channelId)
	return c
}

// Hl sets the optional parameter "hl": Returen content in specified
// language
func (c *PlaylistsListCall) Hl(hl string) *PlaylistsListCall {
	c.urlParams_.Set("hl", hl)
	return c
}

// Id sets the optional parameter "id": Return the playlists with the
// given IDs for Stubby or Apiary.
func (c *PlaylistsListCall) Id(id ...string) *PlaylistsListCall {
	c.urlParams_.SetMulti("id", append([]string{}, id...))
	return c
}

// MaxResults sets the optional parameter "maxResults": The *maxResults*
// parameter specifies the maximum number of items that should be
// returned in the result set.
func (c *PlaylistsListCall) MaxResults(maxResults int64) *PlaylistsListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// Mine sets the optional parameter "mine": Return the playlists owned
// by the authenticated user.
func (c *PlaylistsListCall) Mine(mine bool) *PlaylistsListCall {
	c.urlParams_.Set("mine", fmt.Sprint(mine))
	return c
}

// OnBehalfOfContentOwner sets the optional parameter
// "onBehalfOfContentOwner": *Note:* This parameter is intended
// exclusively for YouTube content partners. The
// *onBehalfOfContentOwner* parameter indicates that the request's
// authorization credentials identify a YouTube CMS user who is acting
// on behalf of the content owner specified in the parameter value. This
// parameter is intended for YouTube content partners that own and
// manage many different YouTube channels. It allows content owners to
// authenticate once and get access to all their video and channel data,
// without having to provide authentication credentials for each
// individual channel. The CMS account that the user authenticates with
// must be linked to the specified YouTube content owner.
func (c *PlaylistsListCall) OnBehalfOfContentOwner(onBehalfOfContentOwner string) *PlaylistsListCall {
	c.urlParams_.Set("onBehalfOfContentOwner", onBehalfOfContentOwner)
	return c
}

// OnBehalfOfContentOwnerChannel sets the optional parameter
// "onBehalfOfContentOwnerChannel": This parameter can only be used in a
// properly authorized request. *Note:* This parameter is intended
// exclusively for YouTube content partners. The
// *onBehalfOfContentOwnerChannel* parameter specifies the YouTube
// channel ID of the channel to which a video is being added. This
// parameter is required when a request specifies a value for the
// onBehalfOfContentOwner parameter, and it can only be used in
// conjunction with that parameter. In addition, the request must be
// authorized using a CMS account that is linked to the content owner
// that the onBehalfOfContentOwner parameter specifies. Finally, the
// channel that the onBehalfOfContentOwnerChannel parameter value
// specifies must be linked to the content owner that the
// onBehalfOfContentOwner parameter specifies. This parameter is
// intended for YouTube content partners that own and manage many
// different YouTube channels. It allows content owners to authenticate
// once and perform actions on behalf of the channel specified in the
// parameter value, without having to provide authentication credentials
// for each separate channel.
func (c *PlaylistsListCall) OnBehalfOfContentOwnerChannel(onBehalfOfContentOwnerChannel string) *PlaylistsListCall {
	c.urlParams_.Set("onBehalfOfContentOwnerChannel", onBehalfOfContentOwnerChannel)
	return c
}

// PageToken sets the optional parameter "pageToken": The *pageToken*
// parameter identifies a specific page in the result set that should be
// returned. In an API response, the nextPageToken and prevPageToken
// properties identify other pages that could be retrieved.
func (c *PlaylistsListCall) PageToken(pageToken string) *PlaylistsListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

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

func (c *PlaylistsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200912")
	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, "youtube/v3/playlists")
	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 "youtube.playlists.list" call.
// Exactly one of *PlaylistListResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *PlaylistListResponse.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 *PlaylistsListCall) Do(opts ...googleapi.CallOption) (*PlaylistListResponse, 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 := &PlaylistListResponse{
		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": "Retrieves a list of resources, possibly filtered.",
	//   "flatPath": "youtube/v3/playlists",
	//   "httpMethod": "GET",
	//   "id": "youtube.playlists.list",
	//   "parameterOrder": [
	//     "part"
	//   ],
	//   "parameters": {
	//     "channelId": {
	//       "description": "Return the playlists owned by the specified channel ID.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "hl": {
	//       "description": "Returen content in specified language",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "id": {
	//       "description": "Return the playlists with the given IDs for Stubby or Apiary.",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "5",
	//       "description": "The *maxResults* parameter specifies the maximum number of items that should be returned in the result set.",
	//       "format": "uint32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "mine": {
	//       "description": "Return the playlists owned by the authenticated user.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "onBehalfOfContentOwner": {
	//       "description": "*Note:* This parameter is intended exclusively for YouTube content partners. The *onBehalfOfContentOwner* parameter indicates that the request's authorization credentials identify a YouTube CMS user who is acting on behalf of the content owner specified in the parameter value. This parameter is intended for YouTube content partners that own and manage many different YouTube channels. It allows content owners to authenticate once and get access to all their video and channel data, without having to provide authentication credentials for each individual channel. The CMS account that the user authenticates with must be linked to the specified YouTube content owner.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "onBehalfOfContentOwnerChannel": {
	//       "description": "This parameter can only be used in a properly authorized request. *Note:* This parameter is intended exclusively for YouTube content partners. The *onBehalfOfContentOwnerChannel* parameter specifies the YouTube channel ID of the channel to which a video is being added. This parameter is required when a request specifies a value for the onBehalfOfContentOwner parameter, and it can only be used in conjunction with that parameter. In addition, the request must be authorized using a CMS account that is linked to the content owner that the onBehalfOfContentOwner parameter specifies. Finally, the channel that the onBehalfOfContentOwnerChannel parameter value specifies must be linked to the content owner that the onBehalfOfContentOwner parameter specifies. This parameter is intended for YouTube content partners that own and manage many different YouTube channels. It allows content owners to authenticate once and perform actions on behalf of the channel specified in the parameter value, without having to provide authentication credentials for each separate channel.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageToken": {
	//       "description": "The *pageToken* parameter identifies a specific page in the result set that should be returned. In an API response, the nextPageToken and prevPageToken properties identify other pages that could be retrieved.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "part": {
	//       "description": "The *part* parameter specifies a comma-separated list of one or more playlist resource properties that the API response will include. If the parameter identifies a property that contains child properties, the child properties will be included in the response. For example, in a playlist resource, the snippet property contains properties like author, title, description, tags, and timeCreated. As such, if you set *part=snippet*, the API response will contain all of those properties.",
	//       "location": "query",
	//       "repeated": true,
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "youtube/v3/playlists",
	//   "response": {
	//     "$ref": "PlaylistListResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/youtube",
	//     "https://www.googleapis.com/auth/youtube.force-ssl",
	//     "https://www.googleapis.com/auth/youtube.readonly",
	//     "https://www.googleapis.com/auth/youtubepartner"
	//   ]
	// }

}

// 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 *PlaylistsListCall) Pages(ctx context.Context, f func(*PlaylistListResponse) 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 "youtube.playlists.update":

type PlaylistsUpdateCall struct {
	s          *Service
	playlist   *Playlist
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Update: Updates an existing resource.
func (r *PlaylistsService) Update(part []string, playlist *Playlist) *PlaylistsUpdateCall {
	c := &PlaylistsUpdateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.urlParams_.SetMulti("part", append([]string{}, part...))
	c.playlist = playlist
	return c
}

// OnBehalfOfContentOwner sets the optional parameter
// "onBehalfOfContentOwner": *Note:* This parameter is intended
// exclusively for YouTube content partners. The
// *onBehalfOfContentOwner* parameter indicates that the request's
// authorization credentials identify a YouTube CMS user who is acting
// on behalf of the content owner specified in the parameter value. This
// parameter is intended for YouTube content partners that own and
// manage many different YouTube channels. It allows content owners to
// authenticate once and get access to all their video and channel data,
// without having to provide authentication credentials for each
// individual channel. The CMS account that the user authenticates with
// must be linked to the specified YouTube content owner.
func (c *PlaylistsUpdateCall) OnBehalfOfContentOwner(onBehalfOfContentOwner string) *PlaylistsUpdateCall {
	c.urlParams_.Set("onBehalfOfContentOwner", onBehalfOfContentOwner)
	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 *PlaylistsUpdateCall) Fields(s ...googleapi.Field) *PlaylistsUpdateCall {
	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 *PlaylistsUpdateCall) Context(ctx context.Context) *PlaylistsUpdateCall {
	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 *PlaylistsUpdateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

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

// Do executes the "youtube.playlists.update" call.
// Exactly one of *Playlist or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Playlist.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 *PlaylistsUpdateCall) Do(opts ...googleapi.CallOption) (*Playlist, 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 := &Playlist{
		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 existing resource.",
	//   "flatPath": "youtube/v3/playlists",
	//   "httpMethod": "PUT",
	//   "id": "youtube.playlists.update",
	//   "parameterOrder": [
	//     "part"
	//   ],
	//   "parameters": {
	//     "onBehalfOfContentOwner": {
	//       "description": "*Note:* This parameter is intended exclusively for YouTube content partners. The *onBehalfOfContentOwner* parameter indicates that the request's authorization credentials identify a YouTube CMS user who is acting on behalf of the content owner specified in the parameter value. This parameter is intended for YouTube content partners that own and manage many different YouTube channels. It allows content owners to authenticate once and get access to all their video and channel data, without having to provide authentication credentials for each individual channel. The CMS account that the user authenticates with must be linked to the specified YouTube content owner.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "part": {
	//       "description": "The *part* parameter serves two purposes in this operation. It identifies the properties that the write operation will set as well as the properties that the API response will include. Note that this method will override the existing values for mutable properties that are contained in any parts that the request body specifies. For example, a playlist's description is contained in the snippet part, which must be included in the request body. If the request does not specify a value for the snippet.description property, the playlist's existing description will be deleted.",
	//       "location": "query",
	//       "repeated": true,
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "youtube/v3/playlists",
	//   "request": {
	//     "$ref": "Playlist"
	//   },
	//   "response": {
	//     "$ref": "Playlist"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/youtube",
	//     "https://www.googleapis.com/auth/youtube.force-ssl",
	//     "https://www.googleapis.com/auth/youtubepartner"
	//   ]
	// }

}

// method id "youtube.search.list":

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

// List: Retrieves a list of search resources
func (r *SearchService) List(part []string) *SearchListCall {
	c := &SearchListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.urlParams_.SetMulti("part", append([]string{}, part...))
	return c
}

// ChannelId sets the optional parameter "channelId": Filter on
// resources belonging to this channelId.
func (c *SearchListCall) ChannelId(channelId string) *SearchListCall {
	c.urlParams_.Set("channelId", channelId)
	return c
}

// ChannelType sets the optional parameter "channelType": Add a filter
// on the channel search.
//
// Possible values:
//   "channelTypeUnspecified"
//   "any"
//   "show"
func (c *SearchListCall) ChannelType(channelType string) *SearchListCall {
	c.urlParams_.Set("channelType", channelType)
	return c
}

// EventType sets the optional parameter "eventType": Filter on the
// livestream status of the videos.
//
// Possible values:
//   "none"
//   "upcoming"
//   "live"
//   "completed"
func (c *SearchListCall) EventType(eventType string) *SearchListCall {
	c.urlParams_.Set("eventType", eventType)
	return c
}

// ForContentOwner sets the optional parameter "forContentOwner": Search
// owned by a content owner.
func (c *SearchListCall) ForContentOwner(forContentOwner bool) *SearchListCall {
	c.urlParams_.Set("forContentOwner", fmt.Sprint(forContentOwner))
	return c
}

// ForDeveloper sets the optional parameter "forDeveloper": Restrict the
// search to only retrieve videos uploaded using the project id of the
// authenticated user.
func (c *SearchListCall) ForDeveloper(forDeveloper bool) *SearchListCall {
	c.urlParams_.Set("forDeveloper", fmt.Sprint(forDeveloper))
	return c
}

// ForMine sets the optional parameter "forMine": Search for the private
// videos of the authenticated user.
func (c *SearchListCall) ForMine(forMine bool) *SearchListCall {
	c.urlParams_.Set("forMine", fmt.Sprint(forMine))
	return c
}

// Location sets the optional parameter "location": Filter on location
// of the video
func (c *SearchListCall) Location(location string) *SearchListCall {
	c.urlParams_.Set("location", location)
	return c
}

// LocationRadius sets the optional parameter "locationRadius": Filter
// on distance from the location (specified above).
func (c *SearchListCall) LocationRadius(locationRadius string) *SearchListCall {
	c.urlParams_.Set("locationRadius", locationRadius)
	return c
}

// MaxResults sets the optional parameter "maxResults": The *maxResults*
// parameter specifies the maximum number of items that should be
// returned in the result set.
func (c *SearchListCall) MaxResults(maxResults int64) *SearchListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// OnBehalfOfContentOwner sets the optional parameter
// "onBehalfOfContentOwner": *Note:* This parameter is intended
// exclusively for YouTube content partners. The
// *onBehalfOfContentOwner* parameter indicates that the request's
// authorization credentials identify a YouTube CMS user who is acting
// on behalf of the content owner specified in the parameter value. This
// parameter is intended for YouTube content partners that own and
// manage many different YouTube channels. It allows content owners to
// authenticate once and get access to all their video and channel data,
// without having to provide authentication credentials for each
// individual channel. The CMS account that the user authenticates with
// must be linked to the specified YouTube content owner.
func (c *SearchListCall) OnBehalfOfContentOwner(onBehalfOfContentOwner string) *SearchListCall {
	c.urlParams_.Set("onBehalfOfContentOwner", onBehalfOfContentOwner)
	return c
}

// Order sets the optional parameter "order": Sort order of the results.
//
// Possible values:
//   "searchSortUnspecified"
//   "date"
//   "rating"
//   "viewCount"
//   "relevance" (default)
//   "title"
//   "videoCount"
func (c *SearchListCall) Order(order string) *SearchListCall {
	c.urlParams_.Set("order", order)
	return c
}

// PageToken sets the optional parameter "pageToken": The *pageToken*
// parameter identifies a specific page in the result set that should be
// returned. In an API response, the nextPageToken and prevPageToken
// properties identify other pages that could be retrieved.
func (c *SearchListCall) PageToken(pageToken string) *SearchListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// PublishedAfter sets the optional parameter "publishedAfter": Filter
// on resources published after this date.
func (c *SearchListCall) PublishedAfter(publishedAfter string) *SearchListCall {
	c.urlParams_.Set("publishedAfter", publishedAfter)
	return c
}

// PublishedBefore sets the optional parameter "publishedBefore": Filter
// on resources published before this date.
func (c *SearchListCall) PublishedBefore(publishedBefore string) *SearchListCall {
	c.urlParams_.Set("publishedBefore", publishedBefore)
	return c
}

// Q sets the optional parameter "q": Textual search terms to match.
func (c *SearchListCall) Q(q string) *SearchListCall {
	c.urlParams_.Set("q", q)
	return c
}

// RegionCode sets the optional parameter "regionCode": Display the
// content as seen by viewers in this country.
func (c *SearchListCall) RegionCode(regionCode string) *SearchListCall {
	c.urlParams_.Set("regionCode", regionCode)
	return c
}

// RelatedToVideoId sets the optional parameter "relatedToVideoId":
// Search related to a resource.
func (c *SearchListCall) RelatedToVideoId(relatedToVideoId string) *SearchListCall {
	c.urlParams_.Set("relatedToVideoId", relatedToVideoId)
	return c
}

// RelevanceLanguage sets the optional parameter "relevanceLanguage":
// Return results relevant to this language.
func (c *SearchListCall) RelevanceLanguage(relevanceLanguage string) *SearchListCall {
	c.urlParams_.Set("relevanceLanguage", relevanceLanguage)
	return c
}

// SafeSearch sets the optional parameter "safeSearch": Indicates
// whether the search results should include restricted content as well
// as standard content.
//
// Possible values:
//   "safeSearchSettingUnspecified"
//   "none"
//   "moderate" (default)
//   "strict"
func (c *SearchListCall) SafeSearch(safeSearch string) *SearchListCall {
	c.urlParams_.Set("safeSearch", safeSearch)
	return c
}

// TopicId sets the optional parameter "topicId": Restrict results to a
// particular topic.
func (c *SearchListCall) TopicId(topicId string) *SearchListCall {
	c.urlParams_.Set("topicId", topicId)
	return c
}

// Type sets the optional parameter "type": Restrict results to a
// particular set of resource types from One Platform.
func (c *SearchListCall) Type(type_ ...string) *SearchListCall {
	c.urlParams_.SetMulti("type", append([]string{}, type_...))
	return c
}

// VideoCaption sets the optional parameter "videoCaption": Filter on
// the presence of captions on the videos.
//
// Possible values:
//   "videoCaptionUnspecified"
//   "any"
//   "closedCaption"
//   "none"
func (c *SearchListCall) VideoCaption(videoCaption string) *SearchListCall {
	c.urlParams_.Set("videoCaption", videoCaption)
	return c
}

// VideoCategoryId sets the optional parameter "videoCategoryId": Filter
// on videos in a specific category.
func (c *SearchListCall) VideoCategoryId(videoCategoryId string) *SearchListCall {
	c.urlParams_.Set("videoCategoryId", videoCategoryId)
	return c
}

// VideoDefinition sets the optional parameter "videoDefinition": Filter
// on the definition of the videos.
//
// Possible values:
//   "any"
//   "standard"
//   "high"
func (c *SearchListCall) VideoDefinition(videoDefinition string) *SearchListCall {
	c.urlParams_.Set("videoDefinition", videoDefinition)
	return c
}

// VideoDimension sets the optional parameter "videoDimension": Filter
// on 3d videos.
//
// Possible values:
//   "any"
//   "2d" - 2d
//   "3d" - 3d
func (c *SearchListCall) VideoDimension(videoDimension string) *SearchListCall {
	c.urlParams_.Set("videoDimension", videoDimension)
	return c
}

// VideoDuration sets the optional parameter "videoDuration": Filter on
// the duration of the videos.
//
// Possible values:
//   "videoDurationUnspecified"
//   "any"
//   "short"
//   "medium"
//   "long"
func (c *SearchListCall) VideoDuration(videoDuration string) *SearchListCall {
	c.urlParams_.Set("videoDuration", videoDuration)
	return c
}

// VideoEmbeddable sets the optional parameter "videoEmbeddable": Filter
// on embeddable videos.
//
// Possible values:
//   "videoEmbeddableUnspecified"
//   "any"
//   "true"
func (c *SearchListCall) VideoEmbeddable(videoEmbeddable string) *SearchListCall {
	c.urlParams_.Set("videoEmbeddable", videoEmbeddable)
	return c
}

// VideoLicense sets the optional parameter "videoLicense": Filter on
// the license of the videos.
//
// Possible values:
//   "any"
//   "youtube"
//   "creativeCommon"
func (c *SearchListCall) VideoLicense(videoLicense string) *SearchListCall {
	c.urlParams_.Set("videoLicense", videoLicense)
	return c
}

// VideoSyndicated sets the optional parameter "videoSyndicated": Filter
// on syndicated videos.
//
// Possible values:
//   "videoSyndicatedUnspecified"
//   "any"
//   "true"
func (c *SearchListCall) VideoSyndicated(videoSyndicated string) *SearchListCall {
	c.urlParams_.Set("videoSyndicated", videoSyndicated)
	return c
}

// VideoType sets the optional parameter "videoType": Filter on videos
// of a specific type.
//
// Possible values:
//   "videoTypeUnspecified"
//   "any"
//   "movie"
//   "episode"
func (c *SearchListCall) VideoType(videoType string) *SearchListCall {
	c.urlParams_.Set("videoType", videoType)
	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 *SearchListCall) Fields(s ...googleapi.Field) *SearchListCall {
	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 *SearchListCall) IfNoneMatch(entityTag string) *SearchListCall {
	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 *SearchListCall) Context(ctx context.Context) *SearchListCall {
	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 *SearchListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *SearchListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200912")
	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, "youtube/v3/search")
	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 "youtube.search.list" call.
// Exactly one of *SearchListResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *SearchListResponse.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 *SearchListCall) Do(opts ...googleapi.CallOption) (*SearchListResponse, 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 := &SearchListResponse{
		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": "Retrieves a list of search resources",
	//   "flatPath": "youtube/v3/search",
	//   "httpMethod": "GET",
	//   "id": "youtube.search.list",
	//   "parameterOrder": [
	//     "part"
	//   ],
	//   "parameters": {
	//     "channelId": {
	//       "description": "Filter on resources belonging to this channelId.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "channelType": {
	//       "description": "Add a filter on the channel search.",
	//       "enum": [
	//         "channelTypeUnspecified",
	//         "any",
	//         "show"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "eventType": {
	//       "description": "Filter on the livestream status of the videos.",
	//       "enum": [
	//         "none",
	//         "upcoming",
	//         "live",
	//         "completed"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         "",
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "forContentOwner": {
	//       "description": "Search owned by a content owner.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "forDeveloper": {
	//       "description": "Restrict the search to only retrieve videos uploaded using the project id of the authenticated user.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "forMine": {
	//       "description": "Search for the private videos of the authenticated user.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "location": {
	//       "description": "Filter on location of the video",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "locationRadius": {
	//       "description": "Filter on distance from the location (specified above).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "5",
	//       "description": "The *maxResults* parameter specifies the maximum number of items that should be returned in the result set.",
	//       "format": "uint32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "onBehalfOfContentOwner": {
	//       "description": "*Note:* This parameter is intended exclusively for YouTube content partners. The *onBehalfOfContentOwner* parameter indicates that the request's authorization credentials identify a YouTube CMS user who is acting on behalf of the content owner specified in the parameter value. This parameter is intended for YouTube content partners that own and manage many different YouTube channels. It allows content owners to authenticate once and get access to all their video and channel data, without having to provide authentication credentials for each individual channel. The CMS account that the user authenticates with must be linked to the specified YouTube content owner.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "order": {
	//       "default": "relevance",
	//       "description": "Sort order of the results.",
	//       "enum": [
	//         "searchSortUnspecified",
	//         "date",
	//         "rating",
	//         "viewCount",
	//         "relevance",
	//         "title",
	//         "videoCount"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageToken": {
	//       "description": "The *pageToken* parameter identifies a specific page in the result set that should be returned. In an API response, the nextPageToken and prevPageToken properties identify other pages that could be retrieved.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "part": {
	//       "description": "The *part* parameter specifies a comma-separated list of one or more search resource properties that the API response will include. Set the parameter value to snippet.",
	//       "location": "query",
	//       "repeated": true,
	//       "required": true,
	//       "type": "string"
	//     },
	//     "publishedAfter": {
	//       "description": "Filter on resources published after this date.",
	//       "format": "google-datetime",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "publishedBefore": {
	//       "description": "Filter on resources published before this date.",
	//       "format": "google-datetime",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "q": {
	//       "description": "Textual search terms to match.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "regionCode": {
	//       "description": "Display the content as seen by viewers in this country.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "relatedToVideoId": {
	//       "description": "Search related to a resource.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "relevanceLanguage": {
	//       "description": "Return results relevant to this language.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "safeSearch": {
	//       "default": "moderate",
	//       "description": "Indicates whether the search results should include restricted content as well as standard content.",
	//       "enum": [
	//         "safeSearchSettingUnspecified",
	//         "none",
	//         "moderate",
	//         "strict"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         "",
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "topicId": {
	//       "description": "Restrict results to a particular topic.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "type": {
	//       "default": "video,channel,playlist",
	//       "description": "Restrict results to a particular set of resource types from One Platform.",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "videoCaption": {
	//       "description": "Filter on the presence of captions on the videos.",
	//       "enum": [
	//         "videoCaptionUnspecified",
	//         "any",
	//         "closedCaption",
	//         "none"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         "",
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "videoCategoryId": {
	//       "description": "Filter on videos in a specific category.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "videoDefinition": {
	//       "description": "Filter on the definition of the videos.",
	//       "enum": [
	//         "any",
	//         "standard",
	//         "high"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "videoDimension": {
	//       "description": "Filter on 3d videos.",
	//       "enum": [
	//         "any",
	//         "2d",
	//         "3d"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         "2d",
	//         "3d"
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "videoDuration": {
	//       "description": "Filter on the duration of the videos.",
	//       "enum": [
	//         "videoDurationUnspecified",
	//         "any",
	//         "short",
	//         "medium",
	//         "long"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         "",
	//         "",
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "videoEmbeddable": {
	//       "description": "Filter on embeddable videos.",
	//       "enum": [
	//         "videoEmbeddableUnspecified",
	//         "any",
	//         "true"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "videoLicense": {
	//       "description": "Filter on the license of the videos.",
	//       "enum": [
	//         "any",
	//         "youtube",
	//         "creativeCommon"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "videoSyndicated": {
	//       "description": "Filter on syndicated videos.",
	//       "enum": [
	//         "videoSyndicatedUnspecified",
	//         "any",
	//         "true"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "videoType": {
	//       "description": "Filter on videos of a specific type.",
	//       "enum": [
	//         "videoTypeUnspecified",
	//         "any",
	//         "movie",
	//         "episode"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         "",
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "youtube/v3/search",
	//   "response": {
	//     "$ref": "SearchListResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/youtube",
	//     "https://www.googleapis.com/auth/youtube.force-ssl",
	//     "https://www.googleapis.com/auth/youtube.readonly",
	//     "https://www.googleapis.com/auth/youtubepartner"
	//   ]
	// }

}

// 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 *SearchListCall) Pages(ctx context.Context, f func(*SearchListResponse) 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 "youtube.sponsors.list":

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

// List: Retrieves a list of sponsors that match the request criteria
// for a channel.
func (r *SponsorsService) List(part []string) *SponsorsListCall {
	c := &SponsorsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.urlParams_.SetMulti("part", append([]string{}, part...))
	return c
}

// Filter sets the optional parameter "filter": Parameter that specifies
// which channel sponsors to return.
//
// Possible values:
//   "sponsorFilterUnknown"
//   "newest" (default)
//   "all"
func (c *SponsorsListCall) Filter(filter string) *SponsorsListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// MaxResults sets the optional parameter "maxResults": The *maxResults*
// parameter specifies the maximum number of items that should be
// returned in the result set.
func (c *SponsorsListCall) MaxResults(maxResults int64) *SponsorsListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// PageToken sets the optional parameter "pageToken": The *pageToken*
// parameter identifies a specific page in the result set that should be
// returned. In an API response, the nextPageToken and prevPageToken
// properties identify other pages that could be retrieved.
func (c *SponsorsListCall) PageToken(pageToken string) *SponsorsListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

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

func (c *SponsorsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200912")
	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, "youtube/v3/sponsors")
	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 "youtube.sponsors.list" call.
// Exactly one of *SponsorListResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *SponsorListResponse.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 *SponsorsListCall) Do(opts ...googleapi.CallOption) (*SponsorListResponse, 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 := &SponsorListResponse{
		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": "Retrieves a list of sponsors that match the request criteria for a channel.",
	//   "flatPath": "youtube/v3/sponsors",
	//   "httpMethod": "GET",
	//   "id": "youtube.sponsors.list",
	//   "parameterOrder": [
	//     "part"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "default": "newest",
	//       "description": "Parameter that specifies which channel sponsors to return.",
	//       "enum": [
	//         "sponsorFilterUnknown",
	//         "newest",
	//         "all"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "5",
	//       "description": "The *maxResults* parameter specifies the maximum number of items that should be returned in the result set.",
	//       "format": "uint32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "The *pageToken* parameter identifies a specific page in the result set that should be returned. In an API response, the nextPageToken and prevPageToken properties identify other pages that could be retrieved.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "part": {
	//       "description": "The *part* parameter specifies the sponsor resource parts that the API response will include. Supported values are id and snippet.",
	//       "location": "query",
	//       "repeated": true,
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "youtube/v3/sponsors",
	//   "response": {
	//     "$ref": "SponsorListResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/youtube",
	//     "https://www.googleapis.com/auth/youtube.force-ssl",
	//     "https://www.googleapis.com/auth/youtube.readonly"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *SponsorsListCall) Pages(ctx context.Context, f func(*SponsorListResponse) 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 "youtube.subscriptions.delete":

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

// Delete: Deletes a resource.
func (r *SubscriptionsService) Delete(id string) *SubscriptionsDeleteCall {
	c := &SubscriptionsDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.urlParams_.Set("id", id)
	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 *SubscriptionsDeleteCall) Fields(s ...googleapi.Field) *SubscriptionsDeleteCall {
	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 *SubscriptionsDeleteCall) Context(ctx context.Context) *SubscriptionsDeleteCall {
	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 *SubscriptionsDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

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

// Do executes the "youtube.subscriptions.delete" call.
func (c *SubscriptionsDeleteCall) Do(opts ...googleapi.CallOption) error {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if err != nil {
		return err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return err
	}
	return nil
	// {
	//   "description": "Deletes a resource.",
	//   "flatPath": "youtube/v3/subscriptions",
	//   "httpMethod": "DELETE",
	//   "id": "youtube.subscriptions.delete",
	//   "parameterOrder": [
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "location": "query",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "youtube/v3/subscriptions",
	//   "scopes": [
	//     "https://www.googleapis.com/auth/youtube",
	//     "https://www.googleapis.com/auth/youtube.force-ssl",
	//     "https://www.googleapis.com/auth/youtubepartner"
	//   ]
	// }

}

// method id "youtube.subscriptions.insert":

type SubscriptionsInsertCall struct {
	s            *Service
	subscription *Subscription
	urlParams_   gensupport.URLParams
	ctx_         context.Context
	header_      http.Header
}

// Insert: Inserts a new resource into this collection.
func (r *SubscriptionsService) Insert(part []string, subscription *Subscription) *SubscriptionsInsertCall {
	c := &SubscriptionsInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.urlParams_.SetMulti("part", append([]string{}, part...))
	c.subscription = subscription
	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 *SubscriptionsInsertCall) Fields(s ...googleapi.Field) *SubscriptionsInsertCall {
	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 *SubscriptionsInsertCall) Context(ctx context.Context) *SubscriptionsInsertCall {
	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 *SubscriptionsInsertCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *SubscriptionsInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200912")
	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.subscription)
	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, "youtube/v3/subscriptions")
	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 "youtube.subscriptions.insert" call.
// Exactly one of *Subscription or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Subscription.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 *SubscriptionsInsertCall) Do(opts ...googleapi.CallOption) (*Subscription, 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 := &Subscription{
		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": "Inserts a new resource into this collection.",
	//   "flatPath": "youtube/v3/subscriptions",
	//   "httpMethod": "POST",
	//   "id": "youtube.subscriptions.insert",
	//   "parameterOrder": [
	//     "part"
	//   ],
	//   "parameters": {
	//     "part": {
	//       "description": "The *part* parameter serves two purposes in this operation. It identifies the properties that the write operation will set as well as the properties that the API response will include.",
	//       "location": "query",
	//       "repeated": true,
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "youtube/v3/subscriptions",
	//   "request": {
	//     "$ref": "Subscription"
	//   },
	//   "response": {
	//     "$ref": "Subscription"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/youtube",
	//     "https://www.googleapis.com/auth/youtube.force-ssl",
	//     "https://www.googleapis.com/auth/youtubepartner"
	//   ]
	// }

}

// method id "youtube.subscriptions.list":

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

// List: Retrieves a list of resources, possibly filtered.
func (r *SubscriptionsService) List(part []string) *SubscriptionsListCall {
	c := &SubscriptionsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.urlParams_.SetMulti("part", append([]string{}, part...))
	return c
}

// ChannelId sets the optional parameter "channelId": Return the
// subscriptions of the given channel owner.
func (c *SubscriptionsListCall) ChannelId(channelId string) *SubscriptionsListCall {
	c.urlParams_.Set("channelId", channelId)
	return c
}

// ForChannelId sets the optional parameter "forChannelId": Return the
// subscriptions to the subset of these channels that the authenticated
// user is subscribed to.
func (c *SubscriptionsListCall) ForChannelId(forChannelId string) *SubscriptionsListCall {
	c.urlParams_.Set("forChannelId", forChannelId)
	return c
}

// Id sets the optional parameter "id": Return the subscriptions with
// the given IDs for Stubby or Apiary.
func (c *SubscriptionsListCall) Id(id ...string) *SubscriptionsListCall {
	c.urlParams_.SetMulti("id", append([]string{}, id...))
	return c
}

// MaxResults sets the optional parameter "maxResults": The *maxResults*
// parameter specifies the maximum number of items that should be
// returned in the result set.
func (c *SubscriptionsListCall) MaxResults(maxResults int64) *SubscriptionsListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// Mine sets the optional parameter "mine": Flag for returning the
// subscriptions of the authenticated user.
func (c *SubscriptionsListCall) Mine(mine bool) *SubscriptionsListCall {
	c.urlParams_.Set("mine", fmt.Sprint(mine))
	return c
}

// MyRecentSubscribers sets the optional parameter
// "myRecentSubscribers":
func (c *SubscriptionsListCall) MyRecentSubscribers(myRecentSubscribers bool) *SubscriptionsListCall {
	c.urlParams_.Set("myRecentSubscribers", fmt.Sprint(myRecentSubscribers))
	return c
}

// MySubscribers sets the optional parameter "mySubscribers": Return the
// subscribers of the given channel owner.
func (c *SubscriptionsListCall) MySubscribers(mySubscribers bool) *SubscriptionsListCall {
	c.urlParams_.Set("mySubscribers", fmt.Sprint(mySubscribers))
	return c
}

// OnBehalfOfContentOwner sets the optional parameter
// "onBehalfOfContentOwner": *Note:* This parameter is intended
// exclusively for YouTube content partners. The
// *onBehalfOfContentOwner* parameter indicates that the request's
// authorization credentials identify a YouTube CMS user who is acting
// on behalf of the content owner specified in the parameter value. This
// parameter is intended for YouTube content partners that own and
// manage many different YouTube channels. It allows content owners to
// authenticate once and get access to all their video and channel data,
// without having to provide authentication credentials for each
// individual channel. The CMS account that the user authenticates with
// must be linked to the specified YouTube content owner.
func (c *SubscriptionsListCall) OnBehalfOfContentOwner(onBehalfOfContentOwner string) *SubscriptionsListCall {
	c.urlParams_.Set("onBehalfOfContentOwner", onBehalfOfContentOwner)
	return c
}

// OnBehalfOfContentOwnerChannel sets the optional parameter
// "onBehalfOfContentOwnerChannel": This parameter can only be used in a
// properly authorized request. *Note:* This parameter is intended
// exclusively for YouTube content partners. The
// *onBehalfOfContentOwnerChannel* parameter specifies the YouTube
// channel ID of the channel to which a video is being added. This
// parameter is required when a request specifies a value for the
// onBehalfOfContentOwner parameter, and it can only be used in
// conjunction with that parameter. In addition, the request must be
// authorized using a CMS account that is linked to the content owner
// that the onBehalfOfContentOwner parameter specifies. Finally, the
// channel that the onBehalfOfContentOwnerChannel parameter value
// specifies must be linked to the content owner that the
// onBehalfOfContentOwner parameter specifies. This parameter is
// intended for YouTube content partners that own and manage many
// different YouTube channels. It allows content owners to authenticate
// once and perform actions on behalf of the channel specified in the
// parameter value, without having to provide authentication credentials
// for each separate channel.
func (c *SubscriptionsListCall) OnBehalfOfContentOwnerChannel(onBehalfOfContentOwnerChannel string) *SubscriptionsListCall {
	c.urlParams_.Set("onBehalfOfContentOwnerChannel", onBehalfOfContentOwnerChannel)
	return c
}

// Order sets the optional parameter "order": The order of the returned
// subscriptions
//
// Possible values:
//   "subscriptionOrderUnspecified"
//   "relevance" (default)
//   "unread"
//   "alphabetical"
func (c *SubscriptionsListCall) Order(order string) *SubscriptionsListCall {
	c.urlParams_.Set("order", order)
	return c
}

// PageToken sets the optional parameter "pageToken": The *pageToken*
// parameter identifies a specific page in the result set that should be
// returned. In an API response, the nextPageToken and prevPageToken
// properties identify other pages that could be retrieved.
func (c *SubscriptionsListCall) PageToken(pageToken string) *SubscriptionsListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

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

func (c *SubscriptionsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200912")
	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, "youtube/v3/subscriptions")
	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 "youtube.subscriptions.list" call.
// Exactly one of *SubscriptionListResponse or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *SubscriptionListResponse.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 *SubscriptionsListCall) Do(opts ...googleapi.CallOption) (*SubscriptionListResponse, 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 := &SubscriptionListResponse{
		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": "Retrieves a list of resources, possibly filtered.",
	//   "flatPath": "youtube/v3/subscriptions",
	//   "httpMethod": "GET",
	//   "id": "youtube.subscriptions.list",
	//   "parameterOrder": [
	//     "part"
	//   ],
	//   "parameters": {
	//     "channelId": {
	//       "description": "Return the subscriptions of the given channel owner.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "forChannelId": {
	//       "description": "Return the subscriptions to the subset of these channels that the authenticated user is subscribed to.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "id": {
	//       "description": "Return the subscriptions with the given IDs for Stubby or Apiary.",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "5",
	//       "description": "The *maxResults* parameter specifies the maximum number of items that should be returned in the result set.",
	//       "format": "uint32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "mine": {
	//       "description": "Flag for returning the subscriptions of the authenticated user.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "myRecentSubscribers": {
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "mySubscribers": {
	//       "description": "Return the subscribers of the given channel owner.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "onBehalfOfContentOwner": {
	//       "description": "*Note:* This parameter is intended exclusively for YouTube content partners. The *onBehalfOfContentOwner* parameter indicates that the request's authorization credentials identify a YouTube CMS user who is acting on behalf of the content owner specified in the parameter value. This parameter is intended for YouTube content partners that own and manage many different YouTube channels. It allows content owners to authenticate once and get access to all their video and channel data, without having to provide authentication credentials for each individual channel. The CMS account that the user authenticates with must be linked to the specified YouTube content owner.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "onBehalfOfContentOwnerChannel": {
	//       "description": "This parameter can only be used in a properly authorized request. *Note:* This parameter is intended exclusively for YouTube content partners. The *onBehalfOfContentOwnerChannel* parameter specifies the YouTube channel ID of the channel to which a video is being added. This parameter is required when a request specifies a value for the onBehalfOfContentOwner parameter, and it can only be used in conjunction with that parameter. In addition, the request must be authorized using a CMS account that is linked to the content owner that the onBehalfOfContentOwner parameter specifies. Finally, the channel that the onBehalfOfContentOwnerChannel parameter value specifies must be linked to the content owner that the onBehalfOfContentOwner parameter specifies. This parameter is intended for YouTube content partners that own and manage many different YouTube channels. It allows content owners to authenticate once and perform actions on behalf of the channel specified in the parameter value, without having to provide authentication credentials for each separate channel.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "order": {
	//       "default": "relevance",
	//       "description": "The order of the returned subscriptions",
	//       "enum": [
	//         "subscriptionOrderUnspecified",
	//         "relevance",
	//         "unread",
	//         "alphabetical"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         "",
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageToken": {
	//       "description": "The *pageToken* parameter identifies a specific page in the result set that should be returned. In an API response, the nextPageToken and prevPageToken properties identify other pages that could be retrieved.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "part": {
	//       "description": "The *part* parameter specifies a comma-separated list of one or more subscription resource properties that the API response will include. If the parameter identifies a property that contains child properties, the child properties will be included in the response. For example, in a subscription resource, the snippet property contains other properties, such as a display title for the subscription. If you set *part=snippet*, the API response will also contain all of those nested properties.",
	//       "location": "query",
	//       "repeated": true,
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "youtube/v3/subscriptions",
	//   "response": {
	//     "$ref": "SubscriptionListResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/youtube",
	//     "https://www.googleapis.com/auth/youtube.force-ssl",
	//     "https://www.googleapis.com/auth/youtube.readonly",
	//     "https://www.googleapis.com/auth/youtubepartner"
	//   ]
	// }

}

// 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 *SubscriptionsListCall) Pages(ctx context.Context, f func(*SubscriptionListResponse) 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 "youtube.superChatEvents.list":

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

// List: Retrieves a list of resources, possibly filtered.
func (r *SuperChatEventsService) List(part []string) *SuperChatEventsListCall {
	c := &SuperChatEventsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.urlParams_.SetMulti("part", append([]string{}, part...))
	return c
}

// Hl sets the optional parameter "hl": Return rendered funding amounts
// in specified language.
func (c *SuperChatEventsListCall) Hl(hl string) *SuperChatEventsListCall {
	c.urlParams_.Set("hl", hl)
	return c
}

// MaxResults sets the optional parameter "maxResults": The *maxResults*
// parameter specifies the maximum number of items that should be
// returned in the result set.
func (c *SuperChatEventsListCall) MaxResults(maxResults int64) *SuperChatEventsListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// PageToken sets the optional parameter "pageToken": The *pageToken*
// parameter identifies a specific page in the result set that should be
// returned. In an API response, the nextPageToken and prevPageToken
// properties identify other pages that could be retrieved.
func (c *SuperChatEventsListCall) PageToken(pageToken string) *SuperChatEventsListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

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

func (c *SuperChatEventsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200912")
	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, "youtube/v3/superChatEvents")
	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 "youtube.superChatEvents.list" call.
// Exactly one of *SuperChatEventListResponse or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *SuperChatEventListResponse.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 *SuperChatEventsListCall) Do(opts ...googleapi.CallOption) (*SuperChatEventListResponse, 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 := &SuperChatEventListResponse{
		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": "Retrieves a list of resources, possibly filtered.",
	//   "flatPath": "youtube/v3/superChatEvents",
	//   "httpMethod": "GET",
	//   "id": "youtube.superChatEvents.list",
	//   "parameterOrder": [
	//     "part"
	//   ],
	//   "parameters": {
	//     "hl": {
	//       "description": "Return rendered funding amounts in specified language.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "5",
	//       "description": "The *maxResults* parameter specifies the maximum number of items that should be returned in the result set.",
	//       "format": "uint32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "The *pageToken* parameter identifies a specific page in the result set that should be returned. In an API response, the nextPageToken and prevPageToken properties identify other pages that could be retrieved.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "part": {
	//       "description": "The *part* parameter specifies the superChatEvent resource parts that the API response will include. Supported values are id and snippet.",
	//       "location": "query",
	//       "repeated": true,
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "youtube/v3/superChatEvents",
	//   "response": {
	//     "$ref": "SuperChatEventListResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/youtube",
	//     "https://www.googleapis.com/auth/youtube.force-ssl",
	//     "https://www.googleapis.com/auth/youtube.readonly"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *SuperChatEventsListCall) Pages(ctx context.Context, f func(*SuperChatEventListResponse) 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 "youtube.tests.insert":

type TestsInsertCall struct {
	s          *Service
	testitem   *TestItem
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Insert: POST method.
func (r *TestsService) Insert(part []string, testitem *TestItem) *TestsInsertCall {
	c := &TestsInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.urlParams_.SetMulti("part", append([]string{}, part...))
	c.testitem = testitem
	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 *TestsInsertCall) Fields(s ...googleapi.Field) *TestsInsertCall {
	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 *TestsInsertCall) Context(ctx context.Context) *TestsInsertCall {
	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 *TestsInsertCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *TestsInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200912")
	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.testitem)
	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, "youtube/v3/tests")
	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 "youtube.tests.insert" call.
// Exactly one of *TestItem or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *TestItem.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 *TestsInsertCall) Do(opts ...googleapi.CallOption) (*TestItem, 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 := &TestItem{
		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": "POST method.",
	//   "flatPath": "youtube/v3/tests",
	//   "httpMethod": "POST",
	//   "id": "youtube.tests.insert",
	//   "parameterOrder": [
	//     "part"
	//   ],
	//   "parameters": {
	//     "part": {
	//       "location": "query",
	//       "repeated": true,
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "youtube/v3/tests",
	//   "request": {
	//     "$ref": "TestItem"
	//   },
	//   "response": {
	//     "$ref": "TestItem"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/youtube.readonly"
	//   ]
	// }

}

// method id "youtube.thirdPartyLinks.delete":

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

// Delete: Deletes a resource.
func (r *ThirdPartyLinksService) Delete(linkingToken string, type_ string) *ThirdPartyLinksDeleteCall {
	c := &ThirdPartyLinksDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.urlParams_.Set("linkingToken", linkingToken)
	c.urlParams_.Set("type", type_)
	return c
}

// Part sets the optional parameter "part": Do not use. Required for
// compatibility.
func (c *ThirdPartyLinksDeleteCall) Part(part ...string) *ThirdPartyLinksDeleteCall {
	c.urlParams_.SetMulti("part", append([]string{}, part...))
	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 *ThirdPartyLinksDeleteCall) Fields(s ...googleapi.Field) *ThirdPartyLinksDeleteCall {
	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 *ThirdPartyLinksDeleteCall) Context(ctx context.Context) *ThirdPartyLinksDeleteCall {
	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 *ThirdPartyLinksDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

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

// Do executes the "youtube.thirdPartyLinks.delete" call.
func (c *ThirdPartyLinksDeleteCall) Do(opts ...googleapi.CallOption) error {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if err != nil {
		return err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return err
	}
	return nil
	// {
	//   "description": "Deletes a resource.",
	//   "flatPath": "youtube/v3/thirdPartyLinks",
	//   "httpMethod": "DELETE",
	//   "id": "youtube.thirdPartyLinks.delete",
	//   "parameterOrder": [
	//     "linkingToken",
	//     "type"
	//   ],
	//   "parameters": {
	//     "linkingToken": {
	//       "description": "Delete the partner links with the given linking token.",
	//       "location": "query",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "part": {
	//       "description": "Do not use. Required for compatibility.",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "type": {
	//       "description": "Type of the link to be deleted.",
	//       "enum": [
	//         "linkUnspecified",
	//         "channelToStoreLink"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         "A link that is connecting (or about to connect) a channel with a store on a merchandising platform in order to enable retail commerce capabilities for that channel on YouTube."
	//       ],
	//       "location": "query",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "youtube/v3/thirdPartyLinks"
	// }

}

// method id "youtube.thirdPartyLinks.insert":

type ThirdPartyLinksInsertCall struct {
	s              *Service
	thirdpartylink *ThirdPartyLink
	urlParams_     gensupport.URLParams
	ctx_           context.Context
	header_        http.Header
}

// Insert: Inserts a new resource into this collection.
func (r *ThirdPartyLinksService) Insert(part []string, thirdpartylink *ThirdPartyLink) *ThirdPartyLinksInsertCall {
	c := &ThirdPartyLinksInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.urlParams_.SetMulti("part", append([]string{}, part...))
	c.thirdpartylink = thirdpartylink
	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 *ThirdPartyLinksInsertCall) Fields(s ...googleapi.Field) *ThirdPartyLinksInsertCall {
	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 *ThirdPartyLinksInsertCall) Context(ctx context.Context) *ThirdPartyLinksInsertCall {
	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 *ThirdPartyLinksInsertCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ThirdPartyLinksInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200912")
	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.thirdpartylink)
	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, "youtube/v3/thirdPartyLinks")
	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 "youtube.thirdPartyLinks.insert" call.
// Exactly one of *ThirdPartyLink or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *ThirdPartyLink.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 *ThirdPartyLinksInsertCall) Do(opts ...googleapi.CallOption) (*ThirdPartyLink, 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 := &ThirdPartyLink{
		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": "Inserts a new resource into this collection.",
	//   "flatPath": "youtube/v3/thirdPartyLinks",
	//   "httpMethod": "POST",
	//   "id": "youtube.thirdPartyLinks.insert",
	//   "parameterOrder": [
	//     "part"
	//   ],
	//   "parameters": {
	//     "part": {
	//       "description": "The *part* parameter specifies the thirdPartyLink resource parts that the API request and response will include. Supported values are linkingToken, status, and snippet.",
	//       "location": "query",
	//       "repeated": true,
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "youtube/v3/thirdPartyLinks",
	//   "request": {
	//     "$ref": "ThirdPartyLink"
	//   },
	//   "response": {
	//     "$ref": "ThirdPartyLink"
	//   }
	// }

}

// method id "youtube.thirdPartyLinks.list":

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

// List: Retrieves a list of resources, possibly filtered.
func (r *ThirdPartyLinksService) List(part []string) *ThirdPartyLinksListCall {
	c := &ThirdPartyLinksListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.urlParams_.SetMulti("part", append([]string{}, part...))
	return c
}

// LinkingToken sets the optional parameter "linkingToken": Get a third
// party link with the given linking token.
func (c *ThirdPartyLinksListCall) LinkingToken(linkingToken string) *ThirdPartyLinksListCall {
	c.urlParams_.Set("linkingToken", linkingToken)
	return c
}

// Type sets the optional parameter "type": Get a third party link of
// the given type.
//
// Possible values:
//   "linkUnspecified"
//   "channelToStoreLink" - A link that is connecting (or about to
// connect) a channel with a store on a merchandising platform in order
// to enable retail commerce capabilities for that channel on YouTube.
func (c *ThirdPartyLinksListCall) Type(type_ string) *ThirdPartyLinksListCall {
	c.urlParams_.Set("type", type_)
	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 *ThirdPartyLinksListCall) Fields(s ...googleapi.Field) *ThirdPartyLinksListCall {
	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 *ThirdPartyLinksListCall) IfNoneMatch(entityTag string) *ThirdPartyLinksListCall {
	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 *ThirdPartyLinksListCall) Context(ctx context.Context) *ThirdPartyLinksListCall {
	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 *ThirdPartyLinksListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ThirdPartyLinksListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200912")
	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, "youtube/v3/thirdPartyLinks")
	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 "youtube.thirdPartyLinks.list" call.
// Exactly one of *ThirdPartyLink or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *ThirdPartyLink.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 *ThirdPartyLinksListCall) Do(opts ...googleapi.CallOption) (*ThirdPartyLink, 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 := &ThirdPartyLink{
		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": "Retrieves a list of resources, possibly filtered.",
	//   "flatPath": "youtube/v3/thirdPartyLinks",
	//   "httpMethod": "GET",
	//   "id": "youtube.thirdPartyLinks.list",
	//   "parameterOrder": [
	//     "part"
	//   ],
	//   "parameters": {
	//     "linkingToken": {
	//       "description": "Get a third party link with the given linking token.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "part": {
	//       "description": "The *part* parameter specifies the thirdPartyLink resource parts that the API response will include. Supported values are linkingToken, status, and snippet.",
	//       "location": "query",
	//       "repeated": true,
	//       "required": true,
	//       "type": "string"
	//     },
	//     "type": {
	//       "description": "Get a third party link of the given type.",
	//       "enum": [
	//         "linkUnspecified",
	//         "channelToStoreLink"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         "A link that is connecting (or about to connect) a channel with a store on a merchandising platform in order to enable retail commerce capabilities for that channel on YouTube."
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "youtube/v3/thirdPartyLinks",
	//   "response": {
	//     "$ref": "ThirdPartyLink"
	//   }
	// }

}

// method id "youtube.thirdPartyLinks.update":

type ThirdPartyLinksUpdateCall struct {
	s              *Service
	thirdpartylink *ThirdPartyLink
	urlParams_     gensupport.URLParams
	ctx_           context.Context
	header_        http.Header
}

// Update: Updates an existing resource.
func (r *ThirdPartyLinksService) Update(part []string, thirdpartylink *ThirdPartyLink) *ThirdPartyLinksUpdateCall {
	c := &ThirdPartyLinksUpdateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.urlParams_.SetMulti("part", append([]string{}, part...))
	c.thirdpartylink = thirdpartylink
	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 *ThirdPartyLinksUpdateCall) Fields(s ...googleapi.Field) *ThirdPartyLinksUpdateCall {
	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 *ThirdPartyLinksUpdateCall) Context(ctx context.Context) *ThirdPartyLinksUpdateCall {
	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 *ThirdPartyLinksUpdateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

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

// Do executes the "youtube.thirdPartyLinks.update" call.
// Exactly one of *ThirdPartyLink or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *ThirdPartyLink.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 *ThirdPartyLinksUpdateCall) Do(opts ...googleapi.CallOption) (*ThirdPartyLink, 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 := &ThirdPartyLink{
		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 existing resource.",
	//   "flatPath": "youtube/v3/thirdPartyLinks",
	//   "httpMethod": "PUT",
	//   "id": "youtube.thirdPartyLinks.update",
	//   "parameterOrder": [
	//     "part"
	//   ],
	//   "parameters": {
	//     "part": {
	//       "description": "The *part* parameter specifies the thirdPartyLink resource parts that the API request and response will include. Supported values are linkingToken, status, and snippet.",
	//       "location": "query",
	//       "repeated": true,
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "youtube/v3/thirdPartyLinks",
	//   "request": {
	//     "$ref": "ThirdPartyLink"
	//   },
	//   "response": {
	//     "$ref": "ThirdPartyLink"
	//   }
	// }

}

// method id "youtube.thumbnails.set":

type ThumbnailsSetCall struct {
	s          *Service
	urlParams_ gensupport.URLParams
	mediaInfo_ *gensupport.MediaInfo
	ctx_       context.Context
	header_    http.Header
}

// Set: As this is not an insert in a strict sense (it supports
// uploading/setting of a thumbnail for multiple videos, which doesn't
// result in creation of a single resource), I use a custom verb here.
func (r *ThumbnailsService) Set(videoId string) *ThumbnailsSetCall {
	c := &ThumbnailsSetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.urlParams_.Set("videoId", videoId)
	return c
}

// OnBehalfOfContentOwner sets the optional parameter
// "onBehalfOfContentOwner": *Note:* This parameter is intended
// exclusively for YouTube content partners. The
// *onBehalfOfContentOwner* parameter indicates that the request's
// authorization credentials identify a YouTube CMS user who is acting
// on behalf of the content owner specified in the parameter value. This
// parameter is intended for YouTube content partners that own and
// manage many different YouTube channels. It allows content owners to
// authenticate once and get access to all their video and channel data,
// without having to provide authentication credentials for each
// individual channel. The actual CMS account that the user
// authenticates with must be linked to the specified YouTube content
// owner.
func (c *ThumbnailsSetCall) OnBehalfOfContentOwner(onBehalfOfContentOwner string) *ThumbnailsSetCall {
	c.urlParams_.Set("onBehalfOfContentOwner", onBehalfOfContentOwner)
	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 *ThumbnailsSetCall) Media(r io.Reader, options ...googleapi.MediaOption) *ThumbnailsSetCall {
	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 *ThumbnailsSetCall) ResumableMedia(ctx context.Context, r io.ReaderAt, size int64, mediaType string) *ThumbnailsSetCall {
	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 *ThumbnailsSetCall) ProgressUpdater(pu googleapi.ProgressUpdater) *ThumbnailsSetCall {
	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 *ThumbnailsSetCall) Fields(s ...googleapi.Field) *ThumbnailsSetCall {
	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 *ThumbnailsSetCall) Context(ctx context.Context) *ThumbnailsSetCall {
	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 *ThumbnailsSetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ThumbnailsSetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200912")
	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, "youtube/v3/thumbnails/set")
	if c.mediaInfo_ != nil {
		urls = googleapi.ResolveRelative(c.s.BasePath, "/upload/youtube/v3/thumbnails/set")
		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
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "youtube.thumbnails.set" call.
// Exactly one of *ThumbnailSetResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *ThumbnailSetResponse.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 *ThumbnailsSetCall) Do(opts ...googleapi.CallOption) (*ThumbnailSetResponse, 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 := &ThumbnailSetResponse{
		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": "As this is not an insert in a strict sense (it supports uploading/setting of a thumbnail for multiple videos, which doesn't result in creation of a single resource), I use a custom verb here.",
	//   "flatPath": "youtube/v3/thumbnails/set",
	//   "httpMethod": "POST",
	//   "id": "youtube.thumbnails.set",
	//   "mediaUpload": {
	//     "accept": [
	//       "image/jpeg",
	//       "image/png",
	//       "application/octet-stream"
	//     ],
	//     "maxSize": "2097152",
	//     "protocols": {
	//       "simple": {
	//         "multipart": true,
	//         "path": "/upload/youtube/v3/thumbnails/set"
	//       }
	//     }
	//   },
	//   "parameterOrder": [
	//     "videoId"
	//   ],
	//   "parameters": {
	//     "onBehalfOfContentOwner": {
	//       "description": "*Note:* This parameter is intended exclusively for YouTube content partners. The *onBehalfOfContentOwner* parameter indicates that the request's authorization credentials identify a YouTube CMS user who is acting on behalf of the content owner specified in the parameter value. This parameter is intended for YouTube content partners that own and manage many different YouTube channels. It allows content owners to authenticate once and get access to all their video and channel data, without having to provide authentication credentials for each individual channel. The actual CMS account that the user authenticates with must be linked to the specified YouTube content owner.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "videoId": {
	//       "description": "Returns the Thumbnail with the given video IDs for Stubby or Apiary.",
	//       "location": "query",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "youtube/v3/thumbnails/set",
	//   "response": {
	//     "$ref": "ThumbnailSetResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/youtube",
	//     "https://www.googleapis.com/auth/youtube.force-ssl",
	//     "https://www.googleapis.com/auth/youtube.upload",
	//     "https://www.googleapis.com/auth/youtubepartner"
	//   ],
	//   "supportsMediaUpload": true
	// }

}

// method id "youtube.videoAbuseReportReasons.list":

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

// List: Retrieves a list of resources, possibly filtered.
func (r *VideoAbuseReportReasonsService) List(part []string) *VideoAbuseReportReasonsListCall {
	c := &VideoAbuseReportReasonsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.urlParams_.SetMulti("part", append([]string{}, part...))
	return c
}

// Hl sets the optional parameter "hl":
func (c *VideoAbuseReportReasonsListCall) Hl(hl string) *VideoAbuseReportReasonsListCall {
	c.urlParams_.Set("hl", hl)
	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 *VideoAbuseReportReasonsListCall) Fields(s ...googleapi.Field) *VideoAbuseReportReasonsListCall {
	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 *VideoAbuseReportReasonsListCall) IfNoneMatch(entityTag string) *VideoAbuseReportReasonsListCall {
	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 *VideoAbuseReportReasonsListCall) Context(ctx context.Context) *VideoAbuseReportReasonsListCall {
	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 *VideoAbuseReportReasonsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *VideoAbuseReportReasonsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200912")
	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, "youtube/v3/videoAbuseReportReasons")
	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 "youtube.videoAbuseReportReasons.list" call.
// Exactly one of *VideoAbuseReportReasonListResponse or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *VideoAbuseReportReasonListResponse.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 *VideoAbuseReportReasonsListCall) Do(opts ...googleapi.CallOption) (*VideoAbuseReportReasonListResponse, 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 := &VideoAbuseReportReasonListResponse{
		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": "Retrieves a list of resources, possibly filtered.",
	//   "flatPath": "youtube/v3/videoAbuseReportReasons",
	//   "httpMethod": "GET",
	//   "id": "youtube.videoAbuseReportReasons.list",
	//   "parameterOrder": [
	//     "part"
	//   ],
	//   "parameters": {
	//     "hl": {
	//       "default": "en_US",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "part": {
	//       "description": "The *part* parameter specifies the videoCategory resource parts that the API response will include. Supported values are id and snippet.",
	//       "location": "query",
	//       "repeated": true,
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "youtube/v3/videoAbuseReportReasons",
	//   "response": {
	//     "$ref": "VideoAbuseReportReasonListResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/youtube",
	//     "https://www.googleapis.com/auth/youtube.force-ssl",
	//     "https://www.googleapis.com/auth/youtube.readonly"
	//   ]
	// }

}

// method id "youtube.videoCategories.list":

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

// List: Retrieves a list of resources, possibly filtered.
func (r *VideoCategoriesService) List(part []string) *VideoCategoriesListCall {
	c := &VideoCategoriesListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.urlParams_.SetMulti("part", append([]string{}, part...))
	return c
}

// Hl sets the optional parameter "hl":
func (c *VideoCategoriesListCall) Hl(hl string) *VideoCategoriesListCall {
	c.urlParams_.Set("hl", hl)
	return c
}

// Id sets the optional parameter "id": Returns the video categories
// with the given IDs for Stubby or Apiary.
func (c *VideoCategoriesListCall) Id(id ...string) *VideoCategoriesListCall {
	c.urlParams_.SetMulti("id", append([]string{}, id...))
	return c
}

// RegionCode sets the optional parameter "regionCode":
func (c *VideoCategoriesListCall) RegionCode(regionCode string) *VideoCategoriesListCall {
	c.urlParams_.Set("regionCode", regionCode)
	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 *VideoCategoriesListCall) Fields(s ...googleapi.Field) *VideoCategoriesListCall {
	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 *VideoCategoriesListCall) IfNoneMatch(entityTag string) *VideoCategoriesListCall {
	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 *VideoCategoriesListCall) Context(ctx context.Context) *VideoCategoriesListCall {
	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 *VideoCategoriesListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *VideoCategoriesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200912")
	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, "youtube/v3/videoCategories")
	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 "youtube.videoCategories.list" call.
// Exactly one of *VideoCategoryListResponse or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *VideoCategoryListResponse.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 *VideoCategoriesListCall) Do(opts ...googleapi.CallOption) (*VideoCategoryListResponse, 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 := &VideoCategoryListResponse{
		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": "Retrieves a list of resources, possibly filtered.",
	//   "flatPath": "youtube/v3/videoCategories",
	//   "httpMethod": "GET",
	//   "id": "youtube.videoCategories.list",
	//   "parameterOrder": [
	//     "part"
	//   ],
	//   "parameters": {
	//     "hl": {
	//       "default": "en-US",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "id": {
	//       "description": "Returns the video categories with the given IDs for Stubby or Apiary.",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "part": {
	//       "description": "The *part* parameter specifies the videoCategory resource properties that the API response will include. Set the parameter value to snippet.",
	//       "location": "query",
	//       "repeated": true,
	//       "required": true,
	//       "type": "string"
	//     },
	//     "regionCode": {
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "youtube/v3/videoCategories",
	//   "response": {
	//     "$ref": "VideoCategoryListResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/youtube",
	//     "https://www.googleapis.com/auth/youtube.force-ssl",
	//     "https://www.googleapis.com/auth/youtube.readonly",
	//     "https://www.googleapis.com/auth/youtubepartner"
	//   ]
	// }

}

// method id "youtube.videos.delete":

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

// Delete: Deletes a resource.
func (r *VideosService) Delete(id string) *VideosDeleteCall {
	c := &VideosDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.urlParams_.Set("id", id)
	return c
}

// OnBehalfOfContentOwner sets the optional parameter
// "onBehalfOfContentOwner": *Note:* This parameter is intended
// exclusively for YouTube content partners. The
// *onBehalfOfContentOwner* parameter indicates that the request's
// authorization credentials identify a YouTube CMS user who is acting
// on behalf of the content owner specified in the parameter value. This
// parameter is intended for YouTube content partners that own and
// manage many different YouTube channels. It allows content owners to
// authenticate once and get access to all their video and channel data,
// without having to provide authentication credentials for each
// individual channel. The actual CMS account that the user
// authenticates with must be linked to the specified YouTube content
// owner.
func (c *VideosDeleteCall) OnBehalfOfContentOwner(onBehalfOfContentOwner string) *VideosDeleteCall {
	c.urlParams_.Set("onBehalfOfContentOwner", onBehalfOfContentOwner)
	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 *VideosDeleteCall) Fields(s ...googleapi.Field) *VideosDeleteCall {
	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 *VideosDeleteCall) Context(ctx context.Context) *VideosDeleteCall {
	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 *VideosDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

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

// Do executes the "youtube.videos.delete" call.
func (c *VideosDeleteCall) Do(opts ...googleapi.CallOption) error {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if err != nil {
		return err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return err
	}
	return nil
	// {
	//   "description": "Deletes a resource.",
	//   "flatPath": "youtube/v3/videos",
	//   "httpMethod": "DELETE",
	//   "id": "youtube.videos.delete",
	//   "parameterOrder": [
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "location": "query",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "onBehalfOfContentOwner": {
	//       "description": "*Note:* This parameter is intended exclusively for YouTube content partners. The *onBehalfOfContentOwner* parameter indicates that the request's authorization credentials identify a YouTube CMS user who is acting on behalf of the content owner specified in the parameter value. This parameter is intended for YouTube content partners that own and manage many different YouTube channels. It allows content owners to authenticate once and get access to all their video and channel data, without having to provide authentication credentials for each individual channel. The actual CMS account that the user authenticates with must be linked to the specified YouTube content owner.",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "youtube/v3/videos",
	//   "scopes": [
	//     "https://www.googleapis.com/auth/youtube",
	//     "https://www.googleapis.com/auth/youtube.force-ssl",
	//     "https://www.googleapis.com/auth/youtubepartner"
	//   ]
	// }

}

// method id "youtube.videos.getRating":

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

// GetRating: Retrieves the ratings that the authorized user gave to a
// list of specified videos.
func (r *VideosService) GetRating(id []string) *VideosGetRatingCall {
	c := &VideosGetRatingCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.urlParams_.SetMulti("id", append([]string{}, id...))
	return c
}

// OnBehalfOfContentOwner sets the optional parameter
// "onBehalfOfContentOwner": *Note:* This parameter is intended
// exclusively for YouTube content partners. The
// *onBehalfOfContentOwner* parameter indicates that the request's
// authorization credentials identify a YouTube CMS user who is acting
// on behalf of the content owner specified in the parameter value. This
// parameter is intended for YouTube content partners that own and
// manage many different YouTube channels. It allows content owners to
// authenticate once and get access to all their video and channel data,
// without having to provide authentication credentials for each
// individual channel. The CMS account that the user authenticates with
// must be linked to the specified YouTube content owner.
func (c *VideosGetRatingCall) OnBehalfOfContentOwner(onBehalfOfContentOwner string) *VideosGetRatingCall {
	c.urlParams_.Set("onBehalfOfContentOwner", onBehalfOfContentOwner)
	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 *VideosGetRatingCall) Fields(s ...googleapi.Field) *VideosGetRatingCall {
	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 *VideosGetRatingCall) IfNoneMatch(entityTag string) *VideosGetRatingCall {
	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 *VideosGetRatingCall) Context(ctx context.Context) *VideosGetRatingCall {
	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 *VideosGetRatingCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *VideosGetRatingCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200912")
	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, "youtube/v3/videos/getRating")
	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 "youtube.videos.getRating" call.
// Exactly one of *VideoRatingListResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *VideoRatingListResponse.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 *VideosGetRatingCall) Do(opts ...googleapi.CallOption) (*VideoRatingListResponse, 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 := &VideoRatingListResponse{
		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": "Retrieves the ratings that the authorized user gave to a list of specified videos.",
	//   "flatPath": "youtube/v3/videos/getRating",
	//   "httpMethod": "GET",
	//   "id": "youtube.videos.getRating",
	//   "parameterOrder": [
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "location": "query",
	//       "repeated": true,
	//       "required": true,
	//       "type": "string"
	//     },
	//     "onBehalfOfContentOwner": {
	//       "description": "*Note:* This parameter is intended exclusively for YouTube content partners. The *onBehalfOfContentOwner* parameter indicates that the request's authorization credentials identify a YouTube CMS user who is acting on behalf of the content owner specified in the parameter value. This parameter is intended for YouTube content partners that own and manage many different YouTube channels. It allows content owners to authenticate once and get access to all their video and channel data, without having to provide authentication credentials for each individual channel. The CMS account that the user authenticates with must be linked to the specified YouTube content owner.",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "youtube/v3/videos/getRating",
	//   "response": {
	//     "$ref": "VideoRatingListResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/youtube",
	//     "https://www.googleapis.com/auth/youtube.force-ssl",
	//     "https://www.googleapis.com/auth/youtubepartner"
	//   ]
	// }

}

// method id "youtube.videos.insert":

type VideosInsertCall struct {
	s          *Service
	video      *Video
	urlParams_ gensupport.URLParams
	mediaInfo_ *gensupport.MediaInfo
	ctx_       context.Context
	header_    http.Header
}

// Insert: Inserts a new resource into this collection.
func (r *VideosService) Insert(part []string, video *Video) *VideosInsertCall {
	c := &VideosInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.urlParams_.SetMulti("part", append([]string{}, part...))
	c.video = video
	return c
}

// AutoLevels sets the optional parameter "autoLevels": Should
// auto-levels be applied to the upload.
func (c *VideosInsertCall) AutoLevels(autoLevels bool) *VideosInsertCall {
	c.urlParams_.Set("autoLevels", fmt.Sprint(autoLevels))
	return c
}

// NotifySubscribers sets the optional parameter "notifySubscribers":
// Notify the channel subscribers about the new video. As default, the
// notification is enabled.
func (c *VideosInsertCall) NotifySubscribers(notifySubscribers bool) *VideosInsertCall {
	c.urlParams_.Set("notifySubscribers", fmt.Sprint(notifySubscribers))
	return c
}

// OnBehalfOfContentOwner sets the optional parameter
// "onBehalfOfContentOwner": *Note:* This parameter is intended
// exclusively for YouTube content partners. The
// *onBehalfOfContentOwner* parameter indicates that the request's
// authorization credentials identify a YouTube CMS user who is acting
// on behalf of the content owner specified in the parameter value. This
// parameter is intended for YouTube content partners that own and
// manage many different YouTube channels. It allows content owners to
// authenticate once and get access to all their video and channel data,
// without having to provide authentication credentials for each
// individual channel. The CMS account that the user authenticates with
// must be linked to the specified YouTube content owner.
func (c *VideosInsertCall) OnBehalfOfContentOwner(onBehalfOfContentOwner string) *VideosInsertCall {
	c.urlParams_.Set("onBehalfOfContentOwner", onBehalfOfContentOwner)
	return c
}

// OnBehalfOfContentOwnerChannel sets the optional parameter
// "onBehalfOfContentOwnerChannel": This parameter can only be used in a
// properly authorized request. *Note:* This parameter is intended
// exclusively for YouTube content partners. The
// *onBehalfOfContentOwnerChannel* parameter specifies the YouTube
// channel ID of the channel to which a video is being added. This
// parameter is required when a request specifies a value for the
// onBehalfOfContentOwner parameter, and it can only be used in
// conjunction with that parameter. In addition, the request must be
// authorized using a CMS account that is linked to the content owner
// that the onBehalfOfContentOwner parameter specifies. Finally, the
// channel that the onBehalfOfContentOwnerChannel parameter value
// specifies must be linked to the content owner that the
// onBehalfOfContentOwner parameter specifies. This parameter is
// intended for YouTube content partners that own and manage many
// different YouTube channels. It allows content owners to authenticate
// once and perform actions on behalf of the channel specified in the
// parameter value, without having to provide authentication credentials
// for each separate channel.
func (c *VideosInsertCall) OnBehalfOfContentOwnerChannel(onBehalfOfContentOwnerChannel string) *VideosInsertCall {
	c.urlParams_.Set("onBehalfOfContentOwnerChannel", onBehalfOfContentOwnerChannel)
	return c
}

// Stabilize sets the optional parameter "stabilize": Should stabilize
// be applied to the upload.
func (c *VideosInsertCall) Stabilize(stabilize bool) *VideosInsertCall {
	c.urlParams_.Set("stabilize", fmt.Sprint(stabilize))
	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 *VideosInsertCall) Media(r io.Reader, options ...googleapi.MediaOption) *VideosInsertCall {
	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 *VideosInsertCall) ResumableMedia(ctx context.Context, r io.ReaderAt, size int64, mediaType string) *VideosInsertCall {
	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 *VideosInsertCall) ProgressUpdater(pu googleapi.ProgressUpdater) *VideosInsertCall {
	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 *VideosInsertCall) Fields(s ...googleapi.Field) *VideosInsertCall {
	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 *VideosInsertCall) Context(ctx context.Context) *VideosInsertCall {
	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 *VideosInsertCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *VideosInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200912")
	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.video)
	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, "youtube/v3/videos")
	if c.mediaInfo_ != nil {
		urls = googleapi.ResolveRelative(c.s.BasePath, "/upload/youtube/v3/videos")
		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
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "youtube.videos.insert" call.
// Exactly one of *Video or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Video.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 *VideosInsertCall) Do(opts ...googleapi.CallOption) (*Video, 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 := &Video{
		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": "Inserts a new resource into this collection.",
	//   "flatPath": "youtube/v3/videos",
	//   "httpMethod": "POST",
	//   "id": "youtube.videos.insert",
	//   "mediaUpload": {
	//     "accept": [
	//       "video/*",
	//       "application/octet-stream"
	//     ],
	//     "maxSize": "137438953472",
	//     "protocols": {
	//       "simple": {
	//         "multipart": true,
	//         "path": "/upload/youtube/v3/videos"
	//       }
	//     }
	//   },
	//   "parameterOrder": [
	//     "part"
	//   ],
	//   "parameters": {
	//     "autoLevels": {
	//       "description": "Should auto-levels be applied to the upload.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "notifySubscribers": {
	//       "default": "true",
	//       "description": "Notify the channel subscribers about the new video. As default, the notification is enabled.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "onBehalfOfContentOwner": {
	//       "description": "*Note:* This parameter is intended exclusively for YouTube content partners. The *onBehalfOfContentOwner* parameter indicates that the request's authorization credentials identify a YouTube CMS user who is acting on behalf of the content owner specified in the parameter value. This parameter is intended for YouTube content partners that own and manage many different YouTube channels. It allows content owners to authenticate once and get access to all their video and channel data, without having to provide authentication credentials for each individual channel. The CMS account that the user authenticates with must be linked to the specified YouTube content owner.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "onBehalfOfContentOwnerChannel": {
	//       "description": "This parameter can only be used in a properly authorized request. *Note:* This parameter is intended exclusively for YouTube content partners. The *onBehalfOfContentOwnerChannel* parameter specifies the YouTube channel ID of the channel to which a video is being added. This parameter is required when a request specifies a value for the onBehalfOfContentOwner parameter, and it can only be used in conjunction with that parameter. In addition, the request must be authorized using a CMS account that is linked to the content owner that the onBehalfOfContentOwner parameter specifies. Finally, the channel that the onBehalfOfContentOwnerChannel parameter value specifies must be linked to the content owner that the onBehalfOfContentOwner parameter specifies. This parameter is intended for YouTube content partners that own and manage many different YouTube channels. It allows content owners to authenticate once and perform actions on behalf of the channel specified in the parameter value, without having to provide authentication credentials for each separate channel.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "part": {
	//       "description": "The *part* parameter serves two purposes in this operation. It identifies the properties that the write operation will set as well as the properties that the API response will include. Note that not all parts contain properties that can be set when inserting or updating a video. For example, the statistics object encapsulates statistics that YouTube calculates for a video and does not contain values that you can set or modify. If the parameter value specifies a part that does not contain mutable values, that part will still be included in the API response.",
	//       "location": "query",
	//       "repeated": true,
	//       "required": true,
	//       "type": "string"
	//     },
	//     "stabilize": {
	//       "description": "Should stabilize be applied to the upload.",
	//       "location": "query",
	//       "type": "boolean"
	//     }
	//   },
	//   "path": "youtube/v3/videos",
	//   "request": {
	//     "$ref": "Video"
	//   },
	//   "response": {
	//     "$ref": "Video"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/youtube",
	//     "https://www.googleapis.com/auth/youtube.force-ssl",
	//     "https://www.googleapis.com/auth/youtube.upload",
	//     "https://www.googleapis.com/auth/youtubepartner"
	//   ],
	//   "supportsMediaUpload": true
	// }

}

// method id "youtube.videos.list":

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

// List: Retrieves a list of resources, possibly filtered.
func (r *VideosService) List(part []string) *VideosListCall {
	c := &VideosListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.urlParams_.SetMulti("part", append([]string{}, part...))
	return c
}

// Chart sets the optional parameter "chart": Return the videos that are
// in the specified chart.
//
// Possible values:
//   "chartUnspecified"
//   "mostPopular"
func (c *VideosListCall) Chart(chart string) *VideosListCall {
	c.urlParams_.Set("chart", chart)
	return c
}

// Hl sets the optional parameter "hl": Stands for "host language".
// Specifies the localization language of the metadata to be filled into
// snippet.localized. The field is filled with the default metadata if
// there is no localization in the specified language. The parameter
// value must be a language code included in the list returned by the
// i18nLanguages.list method (e.g. en_US, es_MX).
func (c *VideosListCall) Hl(hl string) *VideosListCall {
	c.urlParams_.Set("hl", hl)
	return c
}

// Id sets the optional parameter "id": Return videos with the given
// ids.
func (c *VideosListCall) Id(id ...string) *VideosListCall {
	c.urlParams_.SetMulti("id", append([]string{}, id...))
	return c
}

// Locale sets the optional parameter "locale":
func (c *VideosListCall) Locale(locale string) *VideosListCall {
	c.urlParams_.Set("locale", locale)
	return c
}

// MaxHeight sets the optional parameter "maxHeight":
func (c *VideosListCall) MaxHeight(maxHeight int64) *VideosListCall {
	c.urlParams_.Set("maxHeight", fmt.Sprint(maxHeight))
	return c
}

// MaxResults sets the optional parameter "maxResults": The *maxResults*
// parameter specifies the maximum number of items that should be
// returned in the result set. *Note:* This parameter is supported for
// use in conjunction with the myRating and chart parameters, but it is
// not supported for use in conjunction with the id parameter.
func (c *VideosListCall) MaxResults(maxResults int64) *VideosListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// MaxWidth sets the optional parameter "maxWidth": Return the player
// with maximum height specified in
func (c *VideosListCall) MaxWidth(maxWidth int64) *VideosListCall {
	c.urlParams_.Set("maxWidth", fmt.Sprint(maxWidth))
	return c
}

// MyRating sets the optional parameter "myRating": Return videos
// liked/disliked by the authenticated user. Does not support
// RateType.RATED_TYPE_NONE.
//
// Possible values:
//   "none"
//   "like"
//   "dislike"
func (c *VideosListCall) MyRating(myRating string) *VideosListCall {
	c.urlParams_.Set("myRating", myRating)
	return c
}

// OnBehalfOfContentOwner sets the optional parameter
// "onBehalfOfContentOwner": *Note:* This parameter is intended
// exclusively for YouTube content partners. The
// *onBehalfOfContentOwner* parameter indicates that the request's
// authorization credentials identify a YouTube CMS user who is acting
// on behalf of the content owner specified in the parameter value. This
// parameter is intended for YouTube content partners that own and
// manage many different YouTube channels. It allows content owners to
// authenticate once and get access to all their video and channel data,
// without having to provide authentication credentials for each
// individual channel. The CMS account that the user authenticates with
// must be linked to the specified YouTube content owner.
func (c *VideosListCall) OnBehalfOfContentOwner(onBehalfOfContentOwner string) *VideosListCall {
	c.urlParams_.Set("onBehalfOfContentOwner", onBehalfOfContentOwner)
	return c
}

// PageToken sets the optional parameter "pageToken": The *pageToken*
// parameter identifies a specific page in the result set that should be
// returned. In an API response, the nextPageToken and prevPageToken
// properties identify other pages that could be retrieved. *Note:* This
// parameter is supported for use in conjunction with the myRating and
// chart parameters, but it is not supported for use in conjunction with
// the id parameter.
func (c *VideosListCall) PageToken(pageToken string) *VideosListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// RegionCode sets the optional parameter "regionCode": Use a chart that
// is specific to the specified region
func (c *VideosListCall) RegionCode(regionCode string) *VideosListCall {
	c.urlParams_.Set("regionCode", regionCode)
	return c
}

// VideoCategoryId sets the optional parameter "videoCategoryId": Use
// chart that is specific to the specified video category
func (c *VideosListCall) VideoCategoryId(videoCategoryId string) *VideosListCall {
	c.urlParams_.Set("videoCategoryId", videoCategoryId)
	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 *VideosListCall) Fields(s ...googleapi.Field) *VideosListCall {
	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 *VideosListCall) IfNoneMatch(entityTag string) *VideosListCall {
	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 *VideosListCall) Context(ctx context.Context) *VideosListCall {
	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 *VideosListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *VideosListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200912")
	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, "youtube/v3/videos")
	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 "youtube.videos.list" call.
// Exactly one of *VideoListResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *VideoListResponse.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 *VideosListCall) Do(opts ...googleapi.CallOption) (*VideoListResponse, 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 := &VideoListResponse{
		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": "Retrieves a list of resources, possibly filtered.",
	//   "flatPath": "youtube/v3/videos",
	//   "httpMethod": "GET",
	//   "id": "youtube.videos.list",
	//   "parameterOrder": [
	//     "part"
	//   ],
	//   "parameters": {
	//     "chart": {
	//       "description": "Return the videos that are in the specified chart.",
	//       "enum": [
	//         "chartUnspecified",
	//         "mostPopular"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "hl": {
	//       "description": "Stands for \"host language\". Specifies the localization language of the metadata to be filled into snippet.localized. The field is filled with the default metadata if there is no localization in the specified language. The parameter value must be a language code included in the list returned by the i18nLanguages.list method (e.g. en_US, es_MX).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "id": {
	//       "description": "Return videos with the given ids.",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "locale": {
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "maxHeight": {
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "maxResults": {
	//       "default": "5",
	//       "description": "The *maxResults* parameter specifies the maximum number of items that should be returned in the result set. *Note:* This parameter is supported for use in conjunction with the myRating and chart parameters, but it is not supported for use in conjunction with the id parameter.",
	//       "format": "uint32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "maxWidth": {
	//       "description": "Return the player with maximum height specified in",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "myRating": {
	//       "description": "Return videos liked/disliked by the authenticated user. Does not support RateType.RATED_TYPE_NONE.",
	//       "enum": [
	//         "none",
	//         "like",
	//         "dislike"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "onBehalfOfContentOwner": {
	//       "description": "*Note:* This parameter is intended exclusively for YouTube content partners. The *onBehalfOfContentOwner* parameter indicates that the request's authorization credentials identify a YouTube CMS user who is acting on behalf of the content owner specified in the parameter value. This parameter is intended for YouTube content partners that own and manage many different YouTube channels. It allows content owners to authenticate once and get access to all their video and channel data, without having to provide authentication credentials for each individual channel. The CMS account that the user authenticates with must be linked to the specified YouTube content owner.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageToken": {
	//       "description": "The *pageToken* parameter identifies a specific page in the result set that should be returned. In an API response, the nextPageToken and prevPageToken properties identify other pages that could be retrieved. *Note:* This parameter is supported for use in conjunction with the myRating and chart parameters, but it is not supported for use in conjunction with the id parameter.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "part": {
	//       "description": "The *part* parameter specifies a comma-separated list of one or more video resource properties that the API response will include. If the parameter identifies a property that contains child properties, the child properties will be included in the response. For example, in a video resource, the snippet property contains the channelId, title, description, tags, and categoryId properties. As such, if you set *part=snippet*, the API response will contain all of those properties.",
	//       "location": "query",
	//       "repeated": true,
	//       "required": true,
	//       "type": "string"
	//     },
	//     "regionCode": {
	//       "description": "Use a chart that is specific to the specified region",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "videoCategoryId": {
	//       "default": "0",
	//       "description": "Use chart that is specific to the specified video category",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "youtube/v3/videos",
	//   "response": {
	//     "$ref": "VideoListResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/youtube",
	//     "https://www.googleapis.com/auth/youtube.force-ssl",
	//     "https://www.googleapis.com/auth/youtube.readonly",
	//     "https://www.googleapis.com/auth/youtubepartner"
	//   ]
	// }

}

// 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 *VideosListCall) Pages(ctx context.Context, f func(*VideoListResponse) 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 "youtube.videos.rate":

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

// Rate: Adds a like or dislike rating to a video or removes a rating
// from a video.
func (r *VideosService) Rate(id string, rating string) *VideosRateCall {
	c := &VideosRateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.urlParams_.Set("id", id)
	c.urlParams_.Set("rating", rating)
	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 *VideosRateCall) Fields(s ...googleapi.Field) *VideosRateCall {
	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 *VideosRateCall) Context(ctx context.Context) *VideosRateCall {
	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 *VideosRateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *VideosRateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200912")
	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, "youtube/v3/videos/rate")
	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 "youtube.videos.rate" call.
func (c *VideosRateCall) Do(opts ...googleapi.CallOption) error {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if err != nil {
		return err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return err
	}
	return nil
	// {
	//   "description": "Adds a like or dislike rating to a video or removes a rating from a video.",
	//   "flatPath": "youtube/v3/videos/rate",
	//   "httpMethod": "POST",
	//   "id": "youtube.videos.rate",
	//   "parameterOrder": [
	//     "id",
	//     "rating"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "location": "query",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "rating": {
	//       "enum": [
	//         "none",
	//         "like",
	//         "dislike"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "youtube/v3/videos/rate",
	//   "scopes": [
	//     "https://www.googleapis.com/auth/youtube",
	//     "https://www.googleapis.com/auth/youtube.force-ssl",
	//     "https://www.googleapis.com/auth/youtubepartner"
	//   ]
	// }

}

// method id "youtube.videos.reportAbuse":

type VideosReportAbuseCall struct {
	s                *Service
	videoabusereport *VideoAbuseReport
	urlParams_       gensupport.URLParams
	ctx_             context.Context
	header_          http.Header
}

// ReportAbuse: Report abuse for a video.
func (r *VideosService) ReportAbuse(videoabusereport *VideoAbuseReport) *VideosReportAbuseCall {
	c := &VideosReportAbuseCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.videoabusereport = videoabusereport
	return c
}

// OnBehalfOfContentOwner sets the optional parameter
// "onBehalfOfContentOwner": *Note:* This parameter is intended
// exclusively for YouTube content partners. The
// *onBehalfOfContentOwner* parameter indicates that the request's
// authorization credentials identify a YouTube CMS user who is acting
// on behalf of the content owner specified in the parameter value. This
// parameter is intended for YouTube content partners that own and
// manage many different YouTube channels. It allows content owners to
// authenticate once and get access to all their video and channel data,
// without having to provide authentication credentials for each
// individual channel. The CMS account that the user authenticates with
// must be linked to the specified YouTube content owner.
func (c *VideosReportAbuseCall) OnBehalfOfContentOwner(onBehalfOfContentOwner string) *VideosReportAbuseCall {
	c.urlParams_.Set("onBehalfOfContentOwner", onBehalfOfContentOwner)
	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 *VideosReportAbuseCall) Fields(s ...googleapi.Field) *VideosReportAbuseCall {
	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 *VideosReportAbuseCall) Context(ctx context.Context) *VideosReportAbuseCall {
	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 *VideosReportAbuseCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *VideosReportAbuseCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200912")
	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.videoabusereport)
	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, "youtube/v3/videos/reportAbuse")
	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 "youtube.videos.reportAbuse" call.
func (c *VideosReportAbuseCall) Do(opts ...googleapi.CallOption) error {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if err != nil {
		return err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return err
	}
	return nil
	// {
	//   "description": "Report abuse for a video.",
	//   "flatPath": "youtube/v3/videos/reportAbuse",
	//   "httpMethod": "POST",
	//   "id": "youtube.videos.reportAbuse",
	//   "parameterOrder": [],
	//   "parameters": {
	//     "onBehalfOfContentOwner": {
	//       "description": "*Note:* This parameter is intended exclusively for YouTube content partners. The *onBehalfOfContentOwner* parameter indicates that the request's authorization credentials identify a YouTube CMS user who is acting on behalf of the content owner specified in the parameter value. This parameter is intended for YouTube content partners that own and manage many different YouTube channels. It allows content owners to authenticate once and get access to all their video and channel data, without having to provide authentication credentials for each individual channel. The CMS account that the user authenticates with must be linked to the specified YouTube content owner.",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "youtube/v3/videos/reportAbuse",
	//   "request": {
	//     "$ref": "VideoAbuseReport"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/youtube",
	//     "https://www.googleapis.com/auth/youtube.force-ssl",
	//     "https://www.googleapis.com/auth/youtubepartner"
	//   ]
	// }

}

// method id "youtube.videos.update":

type VideosUpdateCall struct {
	s          *Service
	video      *Video
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Update: Updates an existing resource.
func (r *VideosService) Update(part []string, video *Video) *VideosUpdateCall {
	c := &VideosUpdateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.urlParams_.SetMulti("part", append([]string{}, part...))
	c.video = video
	return c
}

// OnBehalfOfContentOwner sets the optional parameter
// "onBehalfOfContentOwner": *Note:* This parameter is intended
// exclusively for YouTube content partners. The
// *onBehalfOfContentOwner* parameter indicates that the request's
// authorization credentials identify a YouTube CMS user who is acting
// on behalf of the content owner specified in the parameter value. This
// parameter is intended for YouTube content partners that own and
// manage many different YouTube channels. It allows content owners to
// authenticate once and get access to all their video and channel data,
// without having to provide authentication credentials for each
// individual channel. The actual CMS account that the user
// authenticates with must be linked to the specified YouTube content
// owner.
func (c *VideosUpdateCall) OnBehalfOfContentOwner(onBehalfOfContentOwner string) *VideosUpdateCall {
	c.urlParams_.Set("onBehalfOfContentOwner", onBehalfOfContentOwner)
	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 *VideosUpdateCall) Fields(s ...googleapi.Field) *VideosUpdateCall {
	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 *VideosUpdateCall) Context(ctx context.Context) *VideosUpdateCall {
	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 *VideosUpdateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

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

// Do executes the "youtube.videos.update" call.
// Exactly one of *Video or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Video.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 *VideosUpdateCall) Do(opts ...googleapi.CallOption) (*Video, 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 := &Video{
		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 existing resource.",
	//   "flatPath": "youtube/v3/videos",
	//   "httpMethod": "PUT",
	//   "id": "youtube.videos.update",
	//   "parameterOrder": [
	//     "part"
	//   ],
	//   "parameters": {
	//     "onBehalfOfContentOwner": {
	//       "description": "*Note:* This parameter is intended exclusively for YouTube content partners. The *onBehalfOfContentOwner* parameter indicates that the request's authorization credentials identify a YouTube CMS user who is acting on behalf of the content owner specified in the parameter value. This parameter is intended for YouTube content partners that own and manage many different YouTube channels. It allows content owners to authenticate once and get access to all their video and channel data, without having to provide authentication credentials for each individual channel. The actual CMS account that the user authenticates with must be linked to the specified YouTube content owner.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "part": {
	//       "description": "The *part* parameter serves two purposes in this operation. It identifies the properties that the write operation will set as well as the properties that the API response will include. Note that this method will override the existing values for all of the mutable properties that are contained in any parts that the parameter value specifies. For example, a video's privacy setting is contained in the status part. As such, if your request is updating a private video, and the request's part parameter value includes the status part, the video's privacy setting will be updated to whatever value the request body specifies. If the request body does not specify a value, the existing privacy setting will be removed and the video will revert to the default privacy setting. In addition, not all parts contain properties that can be set when inserting or updating a video. For example, the statistics object encapsulates statistics that YouTube calculates for a video and does not contain values that you can set or modify. If the parameter value specifies a part that does not contain mutable values, that part will still be included in the API response.",
	//       "location": "query",
	//       "repeated": true,
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "youtube/v3/videos",
	//   "request": {
	//     "$ref": "Video"
	//   },
	//   "response": {
	//     "$ref": "Video"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/youtube",
	//     "https://www.googleapis.com/auth/youtube.force-ssl",
	//     "https://www.googleapis.com/auth/youtubepartner"
	//   ]
	// }

}

// method id "youtube.watermarks.set":

type WatermarksSetCall struct {
	s               *Service
	invideobranding *InvideoBranding
	urlParams_      gensupport.URLParams
	mediaInfo_      *gensupport.MediaInfo
	ctx_            context.Context
	header_         http.Header
}

// Set: Allows upload of watermark image and setting it for a channel.
func (r *WatermarksService) Set(channelId string, invideobranding *InvideoBranding) *WatermarksSetCall {
	c := &WatermarksSetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.urlParams_.Set("channelId", channelId)
	c.invideobranding = invideobranding
	return c
}

// OnBehalfOfContentOwner sets the optional parameter
// "onBehalfOfContentOwner": *Note:* This parameter is intended
// exclusively for YouTube content partners. The
// *onBehalfOfContentOwner* parameter indicates that the request's
// authorization credentials identify a YouTube CMS user who is acting
// on behalf of the content owner specified in the parameter value. This
// parameter is intended for YouTube content partners that own and
// manage many different YouTube channels. It allows content owners to
// authenticate once and get access to all their video and channel data,
// without having to provide authentication credentials for each
// individual channel. The CMS account that the user authenticates with
// must be linked to the specified YouTube content owner.
func (c *WatermarksSetCall) OnBehalfOfContentOwner(onBehalfOfContentOwner string) *WatermarksSetCall {
	c.urlParams_.Set("onBehalfOfContentOwner", onBehalfOfContentOwner)
	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 *WatermarksSetCall) Media(r io.Reader, options ...googleapi.MediaOption) *WatermarksSetCall {
	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 *WatermarksSetCall) ResumableMedia(ctx context.Context, r io.ReaderAt, size int64, mediaType string) *WatermarksSetCall {
	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 *WatermarksSetCall) ProgressUpdater(pu googleapi.ProgressUpdater) *WatermarksSetCall {
	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 *WatermarksSetCall) Fields(s ...googleapi.Field) *WatermarksSetCall {
	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 *WatermarksSetCall) Context(ctx context.Context) *WatermarksSetCall {
	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 *WatermarksSetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *WatermarksSetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200912")
	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.invideobranding)
	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, "youtube/v3/watermarks/set")
	if c.mediaInfo_ != nil {
		urls = googleapi.ResolveRelative(c.s.BasePath, "/upload/youtube/v3/watermarks/set")
		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
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "youtube.watermarks.set" call.
func (c *WatermarksSetCall) Do(opts ...googleapi.CallOption) error {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if err != nil {
		return err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return 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 err
		}
		defer res.Body.Close()
		if err := googleapi.CheckResponse(res); err != nil {
			return err
		}
	}
	return nil
	// {
	//   "description": "Allows upload of watermark image and setting it for a channel.",
	//   "flatPath": "youtube/v3/watermarks/set",
	//   "httpMethod": "POST",
	//   "id": "youtube.watermarks.set",
	//   "mediaUpload": {
	//     "accept": [
	//       "image/jpeg",
	//       "image/png",
	//       "application/octet-stream"
	//     ],
	//     "maxSize": "10485760",
	//     "protocols": {
	//       "simple": {
	//         "multipart": true,
	//         "path": "/upload/youtube/v3/watermarks/set"
	//       }
	//     }
	//   },
	//   "parameterOrder": [
	//     "channelId"
	//   ],
	//   "parameters": {
	//     "channelId": {
	//       "location": "query",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "onBehalfOfContentOwner": {
	//       "description": "*Note:* This parameter is intended exclusively for YouTube content partners. The *onBehalfOfContentOwner* parameter indicates that the request's authorization credentials identify a YouTube CMS user who is acting on behalf of the content owner specified in the parameter value. This parameter is intended for YouTube content partners that own and manage many different YouTube channels. It allows content owners to authenticate once and get access to all their video and channel data, without having to provide authentication credentials for each individual channel. The CMS account that the user authenticates with must be linked to the specified YouTube content owner.",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "youtube/v3/watermarks/set",
	//   "request": {
	//     "$ref": "InvideoBranding"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/youtube",
	//     "https://www.googleapis.com/auth/youtube.force-ssl",
	//     "https://www.googleapis.com/auth/youtube.upload",
	//     "https://www.googleapis.com/auth/youtubepartner"
	//   ],
	//   "supportsMediaUpload": true
	// }

}

// method id "youtube.watermarks.unset":

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

// Unset: Allows removal of channel watermark.
func (r *WatermarksService) Unset(channelId string) *WatermarksUnsetCall {
	c := &WatermarksUnsetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.urlParams_.Set("channelId", channelId)
	return c
}

// OnBehalfOfContentOwner sets the optional parameter
// "onBehalfOfContentOwner": *Note:* This parameter is intended
// exclusively for YouTube content partners. The
// *onBehalfOfContentOwner* parameter indicates that the request's
// authorization credentials identify a YouTube CMS user who is acting
// on behalf of the content owner specified in the parameter value. This
// parameter is intended for YouTube content partners that own and
// manage many different YouTube channels. It allows content owners to
// authenticate once and get access to all their video and channel data,
// without having to provide authentication credentials for each
// individual channel. The CMS account that the user authenticates with
// must be linked to the specified YouTube content owner.
func (c *WatermarksUnsetCall) OnBehalfOfContentOwner(onBehalfOfContentOwner string) *WatermarksUnsetCall {
	c.urlParams_.Set("onBehalfOfContentOwner", onBehalfOfContentOwner)
	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 *WatermarksUnsetCall) Fields(s ...googleapi.Field) *WatermarksUnsetCall {
	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 *WatermarksUnsetCall) Context(ctx context.Context) *WatermarksUnsetCall {
	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 *WatermarksUnsetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *WatermarksUnsetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200912")
	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, "youtube/v3/watermarks/unset")
	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 "youtube.watermarks.unset" call.
func (c *WatermarksUnsetCall) Do(opts ...googleapi.CallOption) error {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if err != nil {
		return err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return err
	}
	return nil
	// {
	//   "description": "Allows removal of channel watermark.",
	//   "flatPath": "youtube/v3/watermarks/unset",
	//   "httpMethod": "POST",
	//   "id": "youtube.watermarks.unset",
	//   "parameterOrder": [
	//     "channelId"
	//   ],
	//   "parameters": {
	//     "channelId": {
	//       "location": "query",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "onBehalfOfContentOwner": {
	//       "description": "*Note:* This parameter is intended exclusively for YouTube content partners. The *onBehalfOfContentOwner* parameter indicates that the request's authorization credentials identify a YouTube CMS user who is acting on behalf of the content owner specified in the parameter value. This parameter is intended for YouTube content partners that own and manage many different YouTube channels. It allows content owners to authenticate once and get access to all their video and channel data, without having to provide authentication credentials for each individual channel. The CMS account that the user authenticates with must be linked to the specified YouTube content owner.",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "youtube/v3/watermarks/unset",
	//   "scopes": [
	//     "https://www.googleapis.com/auth/youtube",
	//     "https://www.googleapis.com/auth/youtube.force-ssl",
	//     "https://www.googleapis.com/auth/youtubepartner"
	//   ]
	// }

}
