// 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 factchecktools provides access to the Fact Check Tools API.
//
// For product documentation, see: https://developers.google.com/fact-check/tools/api/
//
// Creating a client
//
// Usage example:
//
//   import "google.golang.org/api/factchecktools/v1alpha1"
//   ...
//   ctx := context.Background()
//   factchecktoolsService, err := factchecktools.NewService(ctx)
//
// In this example, Google Application Default Credentials are used for authentication.
//
// For information on how to create and obtain Application Default Credentials, see https://developers.google.com/identity/protocols/application-default-credentials.
//
// Other authentication options
//
// To use an API key for authentication (note: some APIs do not support API keys), use option.WithAPIKey:
//
//   factchecktoolsService, err := factchecktools.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, ...)
//   factchecktoolsService, err := factchecktools.NewService(ctx, option.WithTokenSource(config.TokenSource(ctx, token)))
//
// See https://godoc.org/google.golang.org/api/option/ for details on options.
package factchecktools // import "google.golang.org/api/factchecktools/v1alpha1"

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

// OAuth2 scopes used by this API.
const (
	// View your email address
	UserinfoEmailScope = "https://www.googleapis.com/auth/userinfo.email"
)

// NewService creates a new Service.
func NewService(ctx context.Context, opts ...option.ClientOption) (*Service, error) {
	scopesOption := option.WithScopes(
		"https://www.googleapis.com/auth/userinfo.email",
	)
	// NOTE: prepend, so we don't override user-specified scopes.
	opts = append([]option.ClientOption{scopesOption}, opts...)
	opts = append(opts, internaloption.WithDefaultEndpoint(basePath))
	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.Claims = NewClaimsService(s)
	s.Pages = NewPagesService(s)
	return s, nil
}

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

	Claims *ClaimsService

	Pages *PagesService
}

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

func NewClaimsService(s *Service) *ClaimsService {
	rs := &ClaimsService{s: s}
	return rs
}

type ClaimsService struct {
	s *Service
}

func NewPagesService(s *Service) *PagesService {
	rs := &PagesService{s: s}
	return rs
}

type PagesService struct {
	s *Service
}

// GoogleFactcheckingFactchecktoolsV1alpha1Claim: Information about the
// claim.
type GoogleFactcheckingFactchecktoolsV1alpha1Claim struct {
	// ClaimDate: The date that the claim was made.
	ClaimDate string `json:"claimDate,omitempty"`

	// ClaimReview: One or more reviews of this claim (namely, a
	// fact-checking article).
	ClaimReview []*GoogleFactcheckingFactchecktoolsV1alpha1ClaimReview `json:"claimReview,omitempty"`

	// Claimant: A person or organization stating the claim. For instance,
	// "John Doe".
	Claimant string `json:"claimant,omitempty"`

	// Text: The claim text. For instance, "Crime has doubled in the last 2
	// years."
	Text string `json:"text,omitempty"`

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

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

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

// GoogleFactcheckingFactchecktoolsV1alpha1ClaimAuthor: Information
// about the claim author.
type GoogleFactcheckingFactchecktoolsV1alpha1ClaimAuthor struct {
	// ImageUrl: Corresponds to `ClaimReview.itemReviewed.author.image`.
	ImageUrl string `json:"imageUrl,omitempty"`

	// JobTitle: Corresponds to `ClaimReview.itemReviewed.author.jobTitle`.
	JobTitle string `json:"jobTitle,omitempty"`

	// Name: A person or organization stating the claim. For instance, "John
	// Doe".<br>
	// Corresponds to `ClaimReview.itemReviewed.author.name`.
	Name string `json:"name,omitempty"`

	// SameAs: Corresponds to `ClaimReview.itemReviewed.author.sameAs`.
	SameAs string `json:"sameAs,omitempty"`

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

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

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

// GoogleFactcheckingFactchecktoolsV1alpha1ClaimRating: Information
// about the claim rating.
type GoogleFactcheckingFactchecktoolsV1alpha1ClaimRating struct {
	// BestRating: For numeric ratings, the best value possible in the scale
	// from worst to
	// best.<br>
	// Corresponds to `ClaimReview.reviewRating.bestRating`.
	BestRating int64 `json:"bestRating,omitempty"`

	// ImageUrl: Corresponds to `ClaimReview.reviewRating.image`.
	ImageUrl string `json:"imageUrl,omitempty"`

	// RatingExplanation: Corresponds to
	// `ClaimReview.reviewRating.ratingExplanation`.
	RatingExplanation string `json:"ratingExplanation,omitempty"`

	// RatingValue: A numeric rating of this claim, in the range worstRating
	// — bestRating
	// inclusive.<br>
	// Corresponds to `ClaimReview.reviewRating.ratingValue`.
	RatingValue int64 `json:"ratingValue,omitempty"`

	// TextualRating: The truthfulness rating as a human-readible short word
	// or phrase.<br>
	// Corresponds to `ClaimReview.reviewRating.alternateName`.
	TextualRating string `json:"textualRating,omitempty"`

	// WorstRating: For numeric ratings, the worst value possible in the
	// scale from worst to
	// best.<br>
	// Corresponds to `ClaimReview.reviewRating.worstRating`.
	WorstRating int64 `json:"worstRating,omitempty"`

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

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

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

// GoogleFactcheckingFactchecktoolsV1alpha1ClaimReview: Information
// about a claim review.
type GoogleFactcheckingFactchecktoolsV1alpha1ClaimReview struct {
	// LanguageCode: The language this review was written in. For instance,
	// "en" or "de".
	LanguageCode string `json:"languageCode,omitempty"`

	// Publisher: The publisher of this claim review.
	Publisher *GoogleFactcheckingFactchecktoolsV1alpha1Publisher `json:"publisher,omitempty"`

	// ReviewDate: The date the claim was reviewed.
	ReviewDate string `json:"reviewDate,omitempty"`

	// TextualRating: Textual rating. For instance, "Mostly false".
	TextualRating string `json:"textualRating,omitempty"`

	// Title: The title of this claim review, if it can be determined.
	Title string `json:"title,omitempty"`

	// Url: The URL of this claim review.
	Url string `json:"url,omitempty"`

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

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

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

// GoogleFactcheckingFactchecktoolsV1alpha1ClaimReviewAuthor:
// Information about the claim review author.
type GoogleFactcheckingFactchecktoolsV1alpha1ClaimReviewAuthor struct {
	// ImageUrl: Corresponds to `ClaimReview.author.image`.
	ImageUrl string `json:"imageUrl,omitempty"`

	// Name: Name of the organization that is publishing the fact
	// check.<br>
	// Corresponds to `ClaimReview.author.name`.
	Name string `json:"name,omitempty"`

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

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

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

// GoogleFactcheckingFactchecktoolsV1alpha1ClaimReviewMarkup: Fields for
// an individual `ClaimReview` element.
// Except for sub-messages that group fields together, each of these
// fields
// correspond those in https://schema.org/ClaimReview. We list the
// precise
// mapping for each field.
type GoogleFactcheckingFactchecktoolsV1alpha1ClaimReviewMarkup struct {
	// ClaimAppearances: A list of links to works in which this claim
	// appears, aside from the one
	// specified in `claim_first_appearance`.<br>
	// Corresponds to
	// `ClaimReview.itemReviewed[@type=Claim].appearance.url`.
	ClaimAppearances []string `json:"claimAppearances,omitempty"`

	// ClaimAuthor: Info about the author of this claim.
	ClaimAuthor *GoogleFactcheckingFactchecktoolsV1alpha1ClaimAuthor `json:"claimAuthor,omitempty"`

	// ClaimDate: The date when the claim was made or entered public
	// discourse.<br>
	// Corresponds to `ClaimReview.itemReviewed.datePublished`.
	ClaimDate string `json:"claimDate,omitempty"`

	// ClaimFirstAppearance: A link to a work in which this claim first
	// appears.<br>
	// Corresponds to
	// `ClaimReview.itemReviewed[@type=Claim].firstAppearance.url`.
	ClaimFirstAppearance string `json:"claimFirstAppearance,omitempty"`

	// ClaimLocation: The location where this claim was
	// made.<br>
	// Corresponds to `ClaimReview.itemReviewed.name`.
	ClaimLocation string `json:"claimLocation,omitempty"`

	// ClaimReviewed: A short summary of the claim being
	// evaluated.<br>
	// Corresponds to `ClaimReview.claimReviewed`.
	ClaimReviewed string `json:"claimReviewed,omitempty"`

	// Rating: Info about the rating of this claim review.
	Rating *GoogleFactcheckingFactchecktoolsV1alpha1ClaimRating `json:"rating,omitempty"`

	// Url: This field is optional, and will default to the page URL. We
	// provide this
	// field to allow you the override the default value, but the only
	// permitted
	// override is the page URL plus an optional anchor link ("page
	// jump").<br>
	// Corresponds to `ClaimReview.url`
	Url string `json:"url,omitempty"`

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

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

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

// GoogleFactcheckingFactchecktoolsV1alpha1ClaimReviewMarkupPage: Holds
// one or more instances of `ClaimReview` markup for a webpage.
type GoogleFactcheckingFactchecktoolsV1alpha1ClaimReviewMarkupPage struct {
	// ClaimReviewAuthor: Info about the author of this claim
	// review.
	// Similar to the above, semantically these are page-level fields, and
	// each
	// `ClaimReview` on this page will contain the same values.
	ClaimReviewAuthor *GoogleFactcheckingFactchecktoolsV1alpha1ClaimReviewAuthor `json:"claimReviewAuthor,omitempty"`

	// ClaimReviewMarkups: A list of individual claim reviews for this
	// page.
	// Each item in the list corresponds to one `ClaimReview` element.
	ClaimReviewMarkups []*GoogleFactcheckingFactchecktoolsV1alpha1ClaimReviewMarkup `json:"claimReviewMarkups,omitempty"`

	// Name: The name of this `ClaimReview` markup page resource, in the
	// form of
	// `pages/{page_id}`. Except for update requests, this field is
	// output-only
	// and should not be set by the user.
	Name string `json:"name,omitempty"`

	// PageUrl: The URL of the page associated with this `ClaimReview`
	// markup.
	// While every individual `ClaimReview` has its own URL field,
	// semantically
	// this is a page-level field, and each `ClaimReview` on this page will
	// use
	// this value unless individually overridden.<br>
	// Corresponds to `ClaimReview.url`
	PageUrl string `json:"pageUrl,omitempty"`

	// PublishDate: The date when the fact check was published.
	// Similar to the URL, semantically this is a page-level field, and
	// each
	// `ClaimReview` on this page will contain the same
	// value.<br>
	// Corresponds to `ClaimReview.datePublished`
	PublishDate string `json:"publishDate,omitempty"`

	// VersionId: The version ID for this markup. Except for update
	// requests, this field is
	// output-only and should not be set by the user.
	VersionId string `json:"versionId,omitempty"`

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

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

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

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

// GoogleFactcheckingFactchecktoolsV1alpha1FactCheckedClaimSearchResponse
// : Response from searching fact-checked claims.
type GoogleFactcheckingFactchecktoolsV1alpha1FactCheckedClaimSearchResponse struct {
	// Claims: The list of claims and all of their associated information.
	Claims []*GoogleFactcheckingFactchecktoolsV1alpha1Claim `json:"claims,omitempty"`

	// NextPageToken: The next pagination token in the Search response. It
	// should be used as the
	// `page_token` for the following request. An empty value means no
	// more
	// results.
	NextPageToken string `json:"nextPageToken,omitempty"`

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

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

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

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

// GoogleFactcheckingFactchecktoolsV1alpha1ListClaimReviewMarkupPagesResp
// onse: Response from listing `ClaimReview` markup.
type GoogleFactcheckingFactchecktoolsV1alpha1ListClaimReviewMarkupPagesResponse struct {
	// ClaimReviewMarkupPages: The result list of pages of `ClaimReview`
	// markup.
	ClaimReviewMarkupPages []*GoogleFactcheckingFactchecktoolsV1alpha1ClaimReviewMarkupPage `json:"claimReviewMarkupPages,omitempty"`

	// NextPageToken: The next pagination token in the Search response. It
	// should be used as the
	// `page_token` for the following request. An empty value means no
	// more
	// results.
	NextPageToken string `json:"nextPageToken,omitempty"`

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

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

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

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

// GoogleFactcheckingFactchecktoolsV1alpha1Publisher: Information about
// the publisher.
type GoogleFactcheckingFactchecktoolsV1alpha1Publisher struct {
	// Name: The name of this publisher. For instance, "Awesome Fact
	// Checks".
	Name string `json:"name,omitempty"`

	// Site: Host-level site name, without the protocol or "www" prefix. For
	// instance,
	// "awesomefactchecks.com". This value of this field is based purely on
	// the
	// claim review URL.
	Site string `json:"site,omitempty"`

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

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

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

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

// method id "factchecktools.claims.search":

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

// Search: Search through fact-checked claims.
func (r *ClaimsService) Search() *ClaimsSearchCall {
	c := &ClaimsSearchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	return c
}

// LanguageCode sets the optional parameter "languageCode": The BCP-47
// language code, such as "en-US" or "sr-Latn". Can be used to
// restrict results by language, though we do not currently consider
// the
// region.
func (c *ClaimsSearchCall) LanguageCode(languageCode string) *ClaimsSearchCall {
	c.urlParams_.Set("languageCode", languageCode)
	return c
}

// MaxAgeDays sets the optional parameter "maxAgeDays": The maximum age
// of the returned search results, in days.
// Age is determined by either claim date or review date, whichever is
// newer.
func (c *ClaimsSearchCall) MaxAgeDays(maxAgeDays int64) *ClaimsSearchCall {
	c.urlParams_.Set("maxAgeDays", fmt.Sprint(maxAgeDays))
	return c
}

// Offset sets the optional parameter "offset": An integer that
// specifies the current offset (that is, starting result
// location) in search results. This field is only considered if
// `page_token`
// is unset. For example, 0 means to return results starting from the
// first
// matching result, and 10 means to return from the 11th result.
func (c *ClaimsSearchCall) Offset(offset int64) *ClaimsSearchCall {
	c.urlParams_.Set("offset", fmt.Sprint(offset))
	return c
}

// PageSize sets the optional parameter "pageSize": The pagination size.
// We will return up to that many results. Defaults to
// 10 if not set.
func (c *ClaimsSearchCall) PageSize(pageSize int64) *ClaimsSearchCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": The pagination
// token. You may provide the `next_page_token` returned from a
// previous List request, if any, in order to get the next page. All
// other
// fields must have the same values as in the previous request.
func (c *ClaimsSearchCall) PageToken(pageToken string) *ClaimsSearchCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Query sets the optional parameter "query": Textual query string.
// Required unless `review_publisher_site_filter` is
// specified.
func (c *ClaimsSearchCall) Query(query string) *ClaimsSearchCall {
	c.urlParams_.Set("query", query)
	return c
}

// ReviewPublisherSiteFilter sets the optional parameter
// "reviewPublisherSiteFilter": The review publisher site to filter
// results by, e.g. nytimes.com.
func (c *ClaimsSearchCall) ReviewPublisherSiteFilter(reviewPublisherSiteFilter string) *ClaimsSearchCall {
	c.urlParams_.Set("reviewPublisherSiteFilter", reviewPublisherSiteFilter)
	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 *ClaimsSearchCall) Fields(s ...googleapi.Field) *ClaimsSearchCall {
	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 *ClaimsSearchCall) IfNoneMatch(entityTag string) *ClaimsSearchCall {
	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 *ClaimsSearchCall) Context(ctx context.Context) *ClaimsSearchCall {
	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 *ClaimsSearchCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ClaimsSearchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200711")
	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, "v1alpha1/claims: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 "factchecktools.claims.search" call.
// Exactly one of
// *GoogleFactcheckingFactchecktoolsV1alpha1FactCheckedClaimSearchRespons
// e or error will be non-nil. Any non-2xx status code is an error.
// Response headers are in either
// *GoogleFactcheckingFactchecktoolsV1alpha1FactCheckedClaimSearchRespons
// e.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 *ClaimsSearchCall) Do(opts ...googleapi.CallOption) (*GoogleFactcheckingFactchecktoolsV1alpha1FactCheckedClaimSearchResponse, 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 := &GoogleFactcheckingFactchecktoolsV1alpha1FactCheckedClaimSearchResponse{
		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": "Search through fact-checked claims.",
	//   "flatPath": "v1alpha1/claims:search",
	//   "httpMethod": "GET",
	//   "id": "factchecktools.claims.search",
	//   "parameterOrder": [],
	//   "parameters": {
	//     "languageCode": {
	//       "description": "The BCP-47 language code, such as \"en-US\" or \"sr-Latn\". Can be used to\nrestrict results by language, though we do not currently consider the\nregion.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "maxAgeDays": {
	//       "description": "The maximum age of the returned search results, in days.\nAge is determined by either claim date or review date, whichever is newer.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "offset": {
	//       "description": "An integer that specifies the current offset (that is, starting result\nlocation) in search results. This field is only considered if `page_token`\nis unset. For example, 0 means to return results starting from the first\nmatching result, and 10 means to return from the 11th result.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageSize": {
	//       "description": "The pagination size. We will return up to that many results. Defaults to\n10 if not set.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "The pagination token. You may provide the `next_page_token` returned from a\nprevious List request, if any, in order to get the next page. All other\nfields must have the same values as in the previous request.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "query": {
	//       "description": "Textual query string. Required unless `review_publisher_site_filter` is\nspecified.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "reviewPublisherSiteFilter": {
	//       "description": "The review publisher site to filter results by, e.g. nytimes.com.",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha1/claims:search",
	//   "response": {
	//     "$ref": "GoogleFactcheckingFactchecktoolsV1alpha1FactCheckedClaimSearchResponse"
	//   }
	// }

}

// 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 *ClaimsSearchCall) Pages(ctx context.Context, f func(*GoogleFactcheckingFactchecktoolsV1alpha1FactCheckedClaimSearchResponse) 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 "factchecktools.pages.create":

type PagesCreateCall struct {
	s                                                             *Service
	googlefactcheckingfactchecktoolsv1alpha1claimreviewmarkuppage *GoogleFactcheckingFactchecktoolsV1alpha1ClaimReviewMarkupPage
	urlParams_                                                    gensupport.URLParams
	ctx_                                                          context.Context
	header_                                                       http.Header
}

// Create: Create `ClaimReview` markup on a page.
func (r *PagesService) Create(googlefactcheckingfactchecktoolsv1alpha1claimreviewmarkuppage *GoogleFactcheckingFactchecktoolsV1alpha1ClaimReviewMarkupPage) *PagesCreateCall {
	c := &PagesCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.googlefactcheckingfactchecktoolsv1alpha1claimreviewmarkuppage = googlefactcheckingfactchecktoolsv1alpha1claimreviewmarkuppage
	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 *PagesCreateCall) Fields(s ...googleapi.Field) *PagesCreateCall {
	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 *PagesCreateCall) Context(ctx context.Context) *PagesCreateCall {
	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 *PagesCreateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *PagesCreateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200711")
	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.googlefactcheckingfactchecktoolsv1alpha1claimreviewmarkuppage)
	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, "v1alpha1/pages")
	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 "factchecktools.pages.create" call.
// Exactly one of
// *GoogleFactcheckingFactchecktoolsV1alpha1ClaimReviewMarkupPage or
// error will be non-nil. Any non-2xx status code is an error. Response
// headers are in either
// *GoogleFactcheckingFactchecktoolsV1alpha1ClaimReviewMarkupPage.ServerR
// esponse.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 *PagesCreateCall) Do(opts ...googleapi.CallOption) (*GoogleFactcheckingFactchecktoolsV1alpha1ClaimReviewMarkupPage, 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 := &GoogleFactcheckingFactchecktoolsV1alpha1ClaimReviewMarkupPage{
		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": "Create `ClaimReview` markup on a page.",
	//   "flatPath": "v1alpha1/pages",
	//   "httpMethod": "POST",
	//   "id": "factchecktools.pages.create",
	//   "parameterOrder": [],
	//   "parameters": {},
	//   "path": "v1alpha1/pages",
	//   "request": {
	//     "$ref": "GoogleFactcheckingFactchecktoolsV1alpha1ClaimReviewMarkupPage"
	//   },
	//   "response": {
	//     "$ref": "GoogleFactcheckingFactchecktoolsV1alpha1ClaimReviewMarkupPage"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/userinfo.email"
	//   ]
	// }

}

// method id "factchecktools.pages.delete":

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

// Delete: Delete all `ClaimReview` markup on a page.
func (r *PagesService) Delete(name string) *PagesDeleteCall {
	c := &PagesDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	return c
}

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

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

// Do executes the "factchecktools.pages.delete" call.
// Exactly one of *GoogleProtobufEmpty or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *GoogleProtobufEmpty.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 *PagesDeleteCall) Do(opts ...googleapi.CallOption) (*GoogleProtobufEmpty, 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 := &GoogleProtobufEmpty{
		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": "Delete all `ClaimReview` markup on a page.",
	//   "flatPath": "v1alpha1/pages/{pagesId}",
	//   "httpMethod": "DELETE",
	//   "id": "factchecktools.pages.delete",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "The name of the resource to delete, in the form of `pages/{page_id}`.",
	//       "location": "path",
	//       "pattern": "^pages/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha1/{+name}",
	//   "response": {
	//     "$ref": "GoogleProtobufEmpty"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/userinfo.email"
	//   ]
	// }

}

// method id "factchecktools.pages.get":

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

// Get: Get all `ClaimReview` markup on a page.
func (r *PagesService) Get(name string) *PagesGetCall {
	c := &PagesGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	return c
}

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

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

// Do executes the "factchecktools.pages.get" call.
// Exactly one of
// *GoogleFactcheckingFactchecktoolsV1alpha1ClaimReviewMarkupPage or
// error will be non-nil. Any non-2xx status code is an error. Response
// headers are in either
// *GoogleFactcheckingFactchecktoolsV1alpha1ClaimReviewMarkupPage.ServerR
// esponse.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 *PagesGetCall) Do(opts ...googleapi.CallOption) (*GoogleFactcheckingFactchecktoolsV1alpha1ClaimReviewMarkupPage, 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 := &GoogleFactcheckingFactchecktoolsV1alpha1ClaimReviewMarkupPage{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Get all `ClaimReview` markup on a page.",
	//   "flatPath": "v1alpha1/pages/{pagesId}",
	//   "httpMethod": "GET",
	//   "id": "factchecktools.pages.get",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "The name of the resource to get, in the form of `pages/{page_id}`.",
	//       "location": "path",
	//       "pattern": "^pages/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha1/{+name}",
	//   "response": {
	//     "$ref": "GoogleFactcheckingFactchecktoolsV1alpha1ClaimReviewMarkupPage"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/userinfo.email"
	//   ]
	// }

}

// method id "factchecktools.pages.list":

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

// List: List the `ClaimReview` markup pages for a specific URL or for
// an
// organization.
func (r *PagesService) List() *PagesListCall {
	c := &PagesListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	return c
}

// Offset sets the optional parameter "offset": An integer that
// specifies the current offset (that is, starting result
// location) in search results. This field is only considered if
// `page_token`
// is unset, and if the request is not for a specific URL. For example,
// 0
// means to return results starting from the first matching result, and
// 10
// means to return from the 11th result.
func (c *PagesListCall) Offset(offset int64) *PagesListCall {
	c.urlParams_.Set("offset", fmt.Sprint(offset))
	return c
}

// Organization sets the optional parameter "organization": The
// organization for which we want to fetch markups for. For
// instance,
// "site.com". Cannot be specified along with an URL.
func (c *PagesListCall) Organization(organization string) *PagesListCall {
	c.urlParams_.Set("organization", organization)
	return c
}

// PageSize sets the optional parameter "pageSize": The pagination size.
// We will return up to that many results. Defaults to
// 10 if not set. Has no effect if a URL is requested.
func (c *PagesListCall) PageSize(pageSize int64) *PagesListCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": The pagination
// token. You may provide the `next_page_token` returned from a
// previous List request, if any, in order to get the next page. All
// other
// fields must have the same values as in the previous request.
func (c *PagesListCall) PageToken(pageToken string) *PagesListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Url sets the optional parameter "url": The URL from which to get
// `ClaimReview` markup. There will be at most one
// result. If markup is associated with a more canonical version of the
// URL
// provided, we will return that URL instead. Cannot be specified along
// with
// an organization.
func (c *PagesListCall) Url(url string) *PagesListCall {
	c.urlParams_.Set("url", url)
	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 *PagesListCall) Fields(s ...googleapi.Field) *PagesListCall {
	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 *PagesListCall) IfNoneMatch(entityTag string) *PagesListCall {
	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 *PagesListCall) Context(ctx context.Context) *PagesListCall {
	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 *PagesListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *PagesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200711")
	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, "v1alpha1/pages")
	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 "factchecktools.pages.list" call.
// Exactly one of
// *GoogleFactcheckingFactchecktoolsV1alpha1ListClaimReviewMarkupPagesRes
// ponse or error will be non-nil. Any non-2xx status code is an error.
// Response headers are in either
// *GoogleFactcheckingFactchecktoolsV1alpha1ListClaimReviewMarkupPagesRes
// ponse.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 *PagesListCall) Do(opts ...googleapi.CallOption) (*GoogleFactcheckingFactchecktoolsV1alpha1ListClaimReviewMarkupPagesResponse, 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 := &GoogleFactcheckingFactchecktoolsV1alpha1ListClaimReviewMarkupPagesResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "List the `ClaimReview` markup pages for a specific URL or for an\norganization.",
	//   "flatPath": "v1alpha1/pages",
	//   "httpMethod": "GET",
	//   "id": "factchecktools.pages.list",
	//   "parameterOrder": [],
	//   "parameters": {
	//     "offset": {
	//       "description": "An integer that specifies the current offset (that is, starting result\nlocation) in search results. This field is only considered if `page_token`\nis unset, and if the request is not for a specific URL. For example, 0\nmeans to return results starting from the first matching result, and 10\nmeans to return from the 11th result.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "organization": {
	//       "description": "The organization for which we want to fetch markups for. For instance,\n\"site.com\". Cannot be specified along with an URL.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageSize": {
	//       "description": "The pagination size. We will return up to that many results. Defaults to\n10 if not set. Has no effect if a URL is requested.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "The pagination token. You may provide the `next_page_token` returned from a\nprevious List request, if any, in order to get the next page. All other\nfields must have the same values as in the previous request.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "url": {
	//       "description": "The URL from which to get `ClaimReview` markup. There will be at most one\nresult. If markup is associated with a more canonical version of the URL\nprovided, we will return that URL instead. Cannot be specified along with\nan organization.",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha1/pages",
	//   "response": {
	//     "$ref": "GoogleFactcheckingFactchecktoolsV1alpha1ListClaimReviewMarkupPagesResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/userinfo.email"
	//   ]
	// }

}

// 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 *PagesListCall) Pages(ctx context.Context, f func(*GoogleFactcheckingFactchecktoolsV1alpha1ListClaimReviewMarkupPagesResponse) 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 "factchecktools.pages.update":

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

// Update: Update for all `ClaimReview` markup on a page
//
// Note that this is a full update. To retain the existing
// `ClaimReview`
// markup on a page, first perform a Get operation, then modify the
// returned
// markup, and finally call Update with the entire `ClaimReview` markup
// as the
// body.
func (r *PagesService) Update(name string, googlefactcheckingfactchecktoolsv1alpha1claimreviewmarkuppage *GoogleFactcheckingFactchecktoolsV1alpha1ClaimReviewMarkupPage) *PagesUpdateCall {
	c := &PagesUpdateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.googlefactcheckingfactchecktoolsv1alpha1claimreviewmarkuppage = googlefactcheckingfactchecktoolsv1alpha1claimreviewmarkuppage
	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 *PagesUpdateCall) Fields(s ...googleapi.Field) *PagesUpdateCall {
	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 *PagesUpdateCall) Context(ctx context.Context) *PagesUpdateCall {
	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 *PagesUpdateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

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

// Do executes the "factchecktools.pages.update" call.
// Exactly one of
// *GoogleFactcheckingFactchecktoolsV1alpha1ClaimReviewMarkupPage or
// error will be non-nil. Any non-2xx status code is an error. Response
// headers are in either
// *GoogleFactcheckingFactchecktoolsV1alpha1ClaimReviewMarkupPage.ServerR
// esponse.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 *PagesUpdateCall) Do(opts ...googleapi.CallOption) (*GoogleFactcheckingFactchecktoolsV1alpha1ClaimReviewMarkupPage, 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 := &GoogleFactcheckingFactchecktoolsV1alpha1ClaimReviewMarkupPage{
		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": "Update for all `ClaimReview` markup on a page\n\nNote that this is a full update. To retain the existing `ClaimReview`\nmarkup on a page, first perform a Get operation, then modify the returned\nmarkup, and finally call Update with the entire `ClaimReview` markup as the\nbody.",
	//   "flatPath": "v1alpha1/pages/{pagesId}",
	//   "httpMethod": "PUT",
	//   "id": "factchecktools.pages.update",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "The name of this `ClaimReview` markup page resource, in the form of\n`pages/{page_id}`. Except for update requests, this field is output-only\nand should not be set by the user.",
	//       "location": "path",
	//       "pattern": "^pages/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha1/{+name}",
	//   "request": {
	//     "$ref": "GoogleFactcheckingFactchecktoolsV1alpha1ClaimReviewMarkupPage"
	//   },
	//   "response": {
	//     "$ref": "GoogleFactcheckingFactchecktoolsV1alpha1ClaimReviewMarkupPage"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/userinfo.email"
	//   ]
	// }

}
