// Package discovery provides access to the APIs Discovery Service.
//
// See https://developers.google.com/discovery/
//
// Usage example:
//
//   import "google.golang.org/api/discovery/v1"
//   ...
//   discoveryService, err := discovery.New(oauthHttpClient)
package discovery

import (
	"bytes"
	"encoding/json"
	"errors"
	"fmt"
	"golang.org/x/net/context"
	"golang.org/x/net/context/ctxhttp"
	"google.golang.org/api/googleapi"
	"google.golang.org/api/internal"
	"io"
	"net/http"
	"net/url"
	"strconv"
	"strings"
)

// 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 _ = googleapi.Version
var _ = errors.New
var _ = strings.Replace

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

func New(client *http.Client) (*Service, error) {
	if client == nil {
		return nil, errors.New("client is nil")
	}
	s := &Service{client: client, BasePath: basePath}
	s.Apis = NewApisService(s)
	return s, nil
}

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

	Apis *ApisService
}

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

func NewApisService(s *Service) *ApisService {
	rs := &ApisService{s: s}
	return rs
}

type ApisService struct {
	s *Service
}

type DirectoryList struct {
	// DiscoveryVersion: Indicate the version of the Discovery API used to
	// generate this doc.
	DiscoveryVersion string `json:"discoveryVersion,omitempty"`

	// Items: The individual directory entries. One entry per api/version
	// pair.
	Items []*DirectoryListItems `json:"items,omitempty"`

	// Kind: The kind for this response.
	Kind string `json:"kind,omitempty"`

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

func (s *DirectoryList) MarshalJSON() ([]byte, error) {
	type noMethod DirectoryList
	raw := noMethod(*s)
	return internal.MarshalJSON(raw, s.ForceSendFields)
}

type DirectoryListItems struct {
	// Description: The description of this API.
	Description string `json:"description,omitempty"`

	// DiscoveryLink: A link to the discovery document.
	DiscoveryLink string `json:"discoveryLink,omitempty"`

	// DiscoveryRestUrl: The URL for the discovery REST document.
	DiscoveryRestUrl string `json:"discoveryRestUrl,omitempty"`

	// DocumentationLink: A link to human readable documentation for the
	// API.
	DocumentationLink string `json:"documentationLink,omitempty"`

	// Icons: Links to 16x16 and 32x32 icons representing the API.
	Icons *DirectoryListItemsIcons `json:"icons,omitempty"`

	// Id: The id of this API.
	Id string `json:"id,omitempty"`

	// Kind: The kind for this response.
	Kind string `json:"kind,omitempty"`

	// Labels: Labels for the status of this API, such as labs or
	// deprecated.
	Labels []string `json:"labels,omitempty"`

	// Name: The name of the API.
	Name string `json:"name,omitempty"`

	// Preferred: True if this version is the preferred version to use.
	Preferred bool `json:"preferred,omitempty"`

	// Title: The title of this API.
	Title string `json:"title,omitempty"`

	// Version: The version of the API.
	Version string `json:"version,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:"-"`
}

func (s *DirectoryListItems) MarshalJSON() ([]byte, error) {
	type noMethod DirectoryListItems
	raw := noMethod(*s)
	return internal.MarshalJSON(raw, s.ForceSendFields)
}

// DirectoryListItemsIcons: Links to 16x16 and 32x32 icons representing
// the API.
type DirectoryListItemsIcons struct {
	// X16: The URL of the 16x16 icon.
	X16 string `json:"x16,omitempty"`

	// X32: The URL of the 32x32 icon.
	X32 string `json:"x32,omitempty"`

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

func (s *DirectoryListItemsIcons) MarshalJSON() ([]byte, error) {
	type noMethod DirectoryListItemsIcons
	raw := noMethod(*s)
	return internal.MarshalJSON(raw, s.ForceSendFields)
}

type JsonSchema struct {
	// Ref: A reference to another schema. The value of this property is the
	// "id" of another schema.
	Ref string `json:"$ref,omitempty"`

	// AdditionalProperties: If this is a schema for an object, this
	// property is the schema for any additional properties with dynamic
	// keys on this object.
	AdditionalProperties *JsonSchema `json:"additionalProperties,omitempty"`

	// Annotations: Additional information about this property.
	Annotations *JsonSchemaAnnotations `json:"annotations,omitempty"`

	// Default: The default value of this property (if one exists).
	Default string `json:"default,omitempty"`

	// Description: A description of this object.
	Description string `json:"description,omitempty"`

	// Enum: Values this parameter may take (if it is an enum).
	Enum []string `json:"enum,omitempty"`

	// EnumDescriptions: The descriptions for the enums. Each position maps
	// to the corresponding value in the "enum" array.
	EnumDescriptions []string `json:"enumDescriptions,omitempty"`

	// Format: An additional regular expression or key that helps constrain
	// the value. For more details see:
	// http://tools.ietf.org/html/draft-zyp-json-schema-03#section-5.23
	Format string `json:"format,omitempty"`

	// Id: Unique identifier for this schema.
	Id string `json:"id,omitempty"`

	// Items: If this is a schema for an array, this property is the schema
	// for each element in the array.
	Items *JsonSchema `json:"items,omitempty"`

	// Location: Whether this parameter goes in the query or the path for
	// REST requests.
	Location string `json:"location,omitempty"`

	// Maximum: The maximum value of this parameter.
	Maximum string `json:"maximum,omitempty"`

	// Minimum: The minimum value of this parameter.
	Minimum string `json:"minimum,omitempty"`

	// Pattern: The regular expression this parameter must conform to. Uses
	// Java 6 regex format:
	// http://docs.oracle.com/javase/6/docs/api/java/util/regex/Pattern.html
	Pattern string `json:"pattern,omitempty"`

	// Properties: If this is a schema for an object, list the schema for
	// each property of this object.
	Properties map[string]JsonSchema `json:"properties,omitempty"`

	// ReadOnly: The value is read-only, generated by the service. The value
	// cannot be modified by the client. If the value is included in a POST,
	// PUT, or PATCH request, it is ignored by the service.
	ReadOnly bool `json:"readOnly,omitempty"`

	// Repeated: Whether this parameter may appear multiple times.
	Repeated bool `json:"repeated,omitempty"`

	// Required: Whether the parameter is required.
	Required bool `json:"required,omitempty"`

	// Type: The value type for this schema. A list of values can be found
	// here: http://tools.ietf.org/html/draft-zyp-json-schema-03#section-5.1
	Type string `json:"type,omitempty"`

	// Variant: In a variant data type, the value of one property is used to
	// determine how to interpret the entire entity. Its value must exist in
	// a map of descriminant values to schema names.
	Variant *JsonSchemaVariant `json:"variant,omitempty"`

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

func (s *JsonSchema) MarshalJSON() ([]byte, error) {
	type noMethod JsonSchema
	raw := noMethod(*s)
	return internal.MarshalJSON(raw, s.ForceSendFields)
}

// JsonSchemaAnnotations: Additional information about this property.
type JsonSchemaAnnotations struct {
	// Required: A list of methods for which this property is required on
	// requests.
	Required []string `json:"required,omitempty"`

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

func (s *JsonSchemaAnnotations) MarshalJSON() ([]byte, error) {
	type noMethod JsonSchemaAnnotations
	raw := noMethod(*s)
	return internal.MarshalJSON(raw, s.ForceSendFields)
}

// JsonSchemaVariant: In a variant data type, the value of one property
// is used to determine how to interpret the entire entity. Its value
// must exist in a map of descriminant values to schema names.
type JsonSchemaVariant struct {
	// Discriminant: The name of the type discriminant property.
	Discriminant string `json:"discriminant,omitempty"`

	// Map: The map of discriminant value to schema to use for parsing..
	Map []*JsonSchemaVariantMap `json:"map,omitempty"`

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

func (s *JsonSchemaVariant) MarshalJSON() ([]byte, error) {
	type noMethod JsonSchemaVariant
	raw := noMethod(*s)
	return internal.MarshalJSON(raw, s.ForceSendFields)
}

type JsonSchemaVariantMap struct {
	Ref string `json:"$ref,omitempty"`

	TypeValue string `json:"type_value,omitempty"`

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

func (s *JsonSchemaVariantMap) MarshalJSON() ([]byte, error) {
	type noMethod JsonSchemaVariantMap
	raw := noMethod(*s)
	return internal.MarshalJSON(raw, s.ForceSendFields)
}

type RestDescription struct {
	// Auth: Authentication information.
	Auth *RestDescriptionAuth `json:"auth,omitempty"`

	// BasePath: [DEPRECATED] The base path for REST requests.
	BasePath string `json:"basePath,omitempty"`

	// BaseUrl: [DEPRECATED] The base URL for REST requests.
	BaseUrl string `json:"baseUrl,omitempty"`

	// BatchPath: The path for REST batch requests.
	BatchPath string `json:"batchPath,omitempty"`

	// CanonicalName: Indicates how the API name should be capitalized and
	// split into various parts. Useful for generating pretty class names.
	CanonicalName string `json:"canonicalName,omitempty"`

	// Description: The description of this API.
	Description string `json:"description,omitempty"`

	// DiscoveryVersion: Indicate the version of the Discovery API used to
	// generate this doc.
	DiscoveryVersion string `json:"discoveryVersion,omitempty"`

	// DocumentationLink: A link to human readable documentation for the
	// API.
	DocumentationLink string `json:"documentationLink,omitempty"`

	// Etag: The ETag for this response.
	Etag string `json:"etag,omitempty"`

	// ExponentialBackoffDefault: Enable exponential backoff for suitable
	// methods in the generated clients.
	ExponentialBackoffDefault bool `json:"exponentialBackoffDefault,omitempty"`

	// Features: A list of supported features for this API.
	Features []string `json:"features,omitempty"`

	// Icons: Links to 16x16 and 32x32 icons representing the API.
	Icons *RestDescriptionIcons `json:"icons,omitempty"`

	// Id: The ID of this API.
	Id string `json:"id,omitempty"`

	// Kind: The kind for this response.
	Kind string `json:"kind,omitempty"`

	// Labels: Labels for the status of this API, such as labs or
	// deprecated.
	Labels []string `json:"labels,omitempty"`

	// Methods: API-level methods for this API.
	Methods map[string]RestMethod `json:"methods,omitempty"`

	// Name: The name of this API.
	Name string `json:"name,omitempty"`

	// OwnerDomain: The domain of the owner of this API. Together with the
	// ownerName and a packagePath values, this can be used to generate a
	// library for this API which would have a unique fully qualified name.
	OwnerDomain string `json:"ownerDomain,omitempty"`

	// OwnerName: The name of the owner of this API. See ownerDomain.
	OwnerName string `json:"ownerName,omitempty"`

	// PackagePath: The package of the owner of this API. See ownerDomain.
	PackagePath string `json:"packagePath,omitempty"`

	// Parameters: Common parameters that apply across all apis.
	Parameters map[string]JsonSchema `json:"parameters,omitempty"`

	// Protocol: The protocol described by this document.
	Protocol string `json:"protocol,omitempty"`

	// Resources: The resources in this API.
	Resources map[string]RestResource `json:"resources,omitempty"`

	// Revision: The version of this API.
	Revision string `json:"revision,omitempty"`

	// RootUrl: The root URL under which all API services live.
	RootUrl string `json:"rootUrl,omitempty"`

	// Schemas: The schemas for this API.
	Schemas map[string]JsonSchema `json:"schemas,omitempty"`

	// ServicePath: The base path for all REST requests.
	ServicePath string `json:"servicePath,omitempty"`

	// Title: The title of this API.
	Title string `json:"title,omitempty"`

	// Version: The version of this API.
	Version string `json:"version,omitempty"`

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

func (s *RestDescription) MarshalJSON() ([]byte, error) {
	type noMethod RestDescription
	raw := noMethod(*s)
	return internal.MarshalJSON(raw, s.ForceSendFields)
}

// RestDescriptionAuth: Authentication information.
type RestDescriptionAuth struct {
	// Oauth2: OAuth 2.0 authentication information.
	Oauth2 *RestDescriptionAuthOauth2 `json:"oauth2,omitempty"`

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

func (s *RestDescriptionAuth) MarshalJSON() ([]byte, error) {
	type noMethod RestDescriptionAuth
	raw := noMethod(*s)
	return internal.MarshalJSON(raw, s.ForceSendFields)
}

// RestDescriptionAuthOauth2: OAuth 2.0 authentication information.
type RestDescriptionAuthOauth2 struct {
	// Scopes: Available OAuth 2.0 scopes.
	Scopes *RestDescriptionAuthOauth2Scopes `json:"scopes,omitempty"`

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

func (s *RestDescriptionAuthOauth2) MarshalJSON() ([]byte, error) {
	type noMethod RestDescriptionAuthOauth2
	raw := noMethod(*s)
	return internal.MarshalJSON(raw, s.ForceSendFields)
}

// RestDescriptionAuthOauth2Scopes: Available OAuth 2.0 scopes.
type RestDescriptionAuthOauth2Scopes struct {
}

// RestDescriptionIcons: Links to 16x16 and 32x32 icons representing the
// API.
type RestDescriptionIcons struct {
	// X16: The URL of the 16x16 icon.
	X16 string `json:"x16,omitempty"`

	// X32: The URL of the 32x32 icon.
	X32 string `json:"x32,omitempty"`

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

func (s *RestDescriptionIcons) MarshalJSON() ([]byte, error) {
	type noMethod RestDescriptionIcons
	raw := noMethod(*s)
	return internal.MarshalJSON(raw, s.ForceSendFields)
}

type RestMethod struct {
	// Description: Description of this method.
	Description string `json:"description,omitempty"`

	// EtagRequired: Whether this method requires an ETag to be specified.
	// The ETag is sent as an HTTP If-Match or If-None-Match header.
	EtagRequired bool `json:"etagRequired,omitempty"`

	// HttpMethod: HTTP method used by this method.
	HttpMethod string `json:"httpMethod,omitempty"`

	// Id: A unique ID for this method. This property can be used to match
	// methods between different versions of Discovery.
	Id string `json:"id,omitempty"`

	// MediaUpload: Media upload parameters.
	MediaUpload *RestMethodMediaUpload `json:"mediaUpload,omitempty"`

	// ParameterOrder: Ordered list of required parameters, serves as a hint
	// to clients on how to structure their method signatures. The array is
	// ordered such that the "most-significant" parameter appears first.
	ParameterOrder []string `json:"parameterOrder,omitempty"`

	// Parameters: Details for all parameters in this method.
	Parameters map[string]JsonSchema `json:"parameters,omitempty"`

	// Path: The URI path of this REST method. Should be used in conjunction
	// with the basePath property at the api-level.
	Path string `json:"path,omitempty"`

	// Request: The schema for the request.
	Request *RestMethodRequest `json:"request,omitempty"`

	// Response: The schema for the response.
	Response *RestMethodResponse `json:"response,omitempty"`

	// Scopes: OAuth 2.0 scopes applicable to this method.
	Scopes []string `json:"scopes,omitempty"`

	// SupportsMediaDownload: Whether this method supports media downloads.
	SupportsMediaDownload bool `json:"supportsMediaDownload,omitempty"`

	// SupportsMediaUpload: Whether this method supports media uploads.
	SupportsMediaUpload bool `json:"supportsMediaUpload,omitempty"`

	// SupportsSubscription: Whether this method supports subscriptions.
	SupportsSubscription bool `json:"supportsSubscription,omitempty"`

	// UseMediaDownloadService: Indicates that downloads from this method
	// should use the download service URL (i.e. "/download"). Only applies
	// if the method supports media download.
	UseMediaDownloadService bool `json:"useMediaDownloadService,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:"-"`
}

func (s *RestMethod) MarshalJSON() ([]byte, error) {
	type noMethod RestMethod
	raw := noMethod(*s)
	return internal.MarshalJSON(raw, s.ForceSendFields)
}

// RestMethodMediaUpload: Media upload parameters.
type RestMethodMediaUpload struct {
	// Accept: MIME Media Ranges for acceptable media uploads to this
	// method.
	Accept []string `json:"accept,omitempty"`

	// MaxSize: Maximum size of a media upload, such as "1MB", "2GB" or
	// "3TB".
	MaxSize string `json:"maxSize,omitempty"`

	// Protocols: Supported upload protocols.
	Protocols *RestMethodMediaUploadProtocols `json:"protocols,omitempty"`

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

func (s *RestMethodMediaUpload) MarshalJSON() ([]byte, error) {
	type noMethod RestMethodMediaUpload
	raw := noMethod(*s)
	return internal.MarshalJSON(raw, s.ForceSendFields)
}

// RestMethodMediaUploadProtocols: Supported upload protocols.
type RestMethodMediaUploadProtocols struct {
	// Resumable: Supports the Resumable Media Upload protocol.
	Resumable *RestMethodMediaUploadProtocolsResumable `json:"resumable,omitempty"`

	// Simple: Supports uploading as a single HTTP request.
	Simple *RestMethodMediaUploadProtocolsSimple `json:"simple,omitempty"`

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

func (s *RestMethodMediaUploadProtocols) MarshalJSON() ([]byte, error) {
	type noMethod RestMethodMediaUploadProtocols
	raw := noMethod(*s)
	return internal.MarshalJSON(raw, s.ForceSendFields)
}

// RestMethodMediaUploadProtocolsResumable: Supports the Resumable Media
// Upload protocol.
type RestMethodMediaUploadProtocolsResumable struct {
	// Multipart: True if this endpoint supports uploading multipart media.
	//
	// Default: true
	Multipart *bool `json:"multipart,omitempty"`

	// Path: The URI path to be used for upload. Should be used in
	// conjunction with the basePath property at the api-level.
	Path string `json:"path,omitempty"`

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

func (s *RestMethodMediaUploadProtocolsResumable) MarshalJSON() ([]byte, error) {
	type noMethod RestMethodMediaUploadProtocolsResumable
	raw := noMethod(*s)
	return internal.MarshalJSON(raw, s.ForceSendFields)
}

// RestMethodMediaUploadProtocolsSimple: Supports uploading as a single
// HTTP request.
type RestMethodMediaUploadProtocolsSimple struct {
	// Multipart: True if this endpoint supports upload multipart media.
	//
	// Default: true
	Multipart *bool `json:"multipart,omitempty"`

	// Path: The URI path to be used for upload. Should be used in
	// conjunction with the basePath property at the api-level.
	Path string `json:"path,omitempty"`

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

func (s *RestMethodMediaUploadProtocolsSimple) MarshalJSON() ([]byte, error) {
	type noMethod RestMethodMediaUploadProtocolsSimple
	raw := noMethod(*s)
	return internal.MarshalJSON(raw, s.ForceSendFields)
}

// RestMethodRequest: The schema for the request.
type RestMethodRequest struct {
	// Ref: Schema ID for the request schema.
	Ref string `json:"$ref,omitempty"`

	// ParameterName: parameter name.
	ParameterName string `json:"parameterName,omitempty"`

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

func (s *RestMethodRequest) MarshalJSON() ([]byte, error) {
	type noMethod RestMethodRequest
	raw := noMethod(*s)
	return internal.MarshalJSON(raw, s.ForceSendFields)
}

// RestMethodResponse: The schema for the response.
type RestMethodResponse struct {
	// Ref: Schema ID for the response schema.
	Ref string `json:"$ref,omitempty"`

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

func (s *RestMethodResponse) MarshalJSON() ([]byte, error) {
	type noMethod RestMethodResponse
	raw := noMethod(*s)
	return internal.MarshalJSON(raw, s.ForceSendFields)
}

type RestResource struct {
	// Methods: Methods on this resource.
	Methods map[string]RestMethod `json:"methods,omitempty"`

	// Resources: Sub-resources on this resource.
	Resources map[string]RestResource `json:"resources,omitempty"`

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

func (s *RestResource) MarshalJSON() ([]byte, error) {
	type noMethod RestResource
	raw := noMethod(*s)
	return internal.MarshalJSON(raw, s.ForceSendFields)
}

// method id "discovery.apis.getRest":

type ApisGetRestCall struct {
	s       *Service
	api     string
	version string
	opt_    map[string]interface{}
	ctx_    context.Context
}

// GetRest: Retrieve the description of a particular version of an api.
func (r *ApisService) GetRest(api string, version string) *ApisGetRestCall {
	c := &ApisGetRestCall{s: r.s, opt_: make(map[string]interface{})}
	c.api = api
	c.version = version
	return c
}

// Fields allows partial responses to be retrieved.
// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *ApisGetRestCall) Fields(s ...googleapi.Field) *ApisGetRestCall {
	c.opt_["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 *ApisGetRestCall) Context(ctx context.Context) *ApisGetRestCall {
	c.ctx_ = ctx
	return c
}

func (c *ApisGetRestCall) doRequest(alt string) (*http.Response, error) {
	var body io.Reader = nil
	params := make(url.Values)
	params.Set("alt", alt)
	if v, ok := c.opt_["fields"]; ok {
		params.Set("fields", fmt.Sprintf("%v", v))
	}
	urls := googleapi.ResolveRelative(c.s.BasePath, "apis/{api}/{version}/rest")
	urls += "?" + params.Encode()
	req, _ := http.NewRequest("GET", urls, body)
	googleapi.Expand(req.URL, map[string]string{
		"api":     c.api,
		"version": c.version,
	})
	req.Header.Set("User-Agent", c.s.userAgent())
	if c.ctx_ != nil {
		return ctxhttp.Do(c.ctx_, c.s.client, req)
	}
	return c.s.client.Do(req)
}

func (c *ApisGetRestCall) Do() (*RestDescription, error) {
	res, err := c.doRequest("json")
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	var ret *RestDescription
	if err := json.NewDecoder(res.Body).Decode(&ret); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieve the description of a particular version of an api.",
	//   "httpMethod": "GET",
	//   "id": "discovery.apis.getRest",
	//   "parameterOrder": [
	//     "api",
	//     "version"
	//   ],
	//   "parameters": {
	//     "api": {
	//       "description": "The name of the API.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "version": {
	//       "description": "The version of the API.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "apis/{api}/{version}/rest",
	//   "response": {
	//     "$ref": "RestDescription"
	//   }
	// }

}

// method id "discovery.apis.list":

type ApisListCall struct {
	s    *Service
	opt_ map[string]interface{}
	ctx_ context.Context
}

// List: Retrieve the list of APIs supported at this endpoint.
func (r *ApisService) List() *ApisListCall {
	c := &ApisListCall{s: r.s, opt_: make(map[string]interface{})}
	return c
}

// Name sets the optional parameter "name": Only include APIs with the
// given name.
func (c *ApisListCall) Name(name string) *ApisListCall {
	c.opt_["name"] = name
	return c
}

// Preferred sets the optional parameter "preferred": Return only the
// preferred version of an API.
func (c *ApisListCall) Preferred(preferred bool) *ApisListCall {
	c.opt_["preferred"] = preferred
	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 *ApisListCall) Fields(s ...googleapi.Field) *ApisListCall {
	c.opt_["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 *ApisListCall) Context(ctx context.Context) *ApisListCall {
	c.ctx_ = ctx
	return c
}

func (c *ApisListCall) doRequest(alt string) (*http.Response, error) {
	var body io.Reader = nil
	params := make(url.Values)
	params.Set("alt", alt)
	if v, ok := c.opt_["name"]; ok {
		params.Set("name", fmt.Sprintf("%v", v))
	}
	if v, ok := c.opt_["preferred"]; ok {
		params.Set("preferred", fmt.Sprintf("%v", v))
	}
	if v, ok := c.opt_["fields"]; ok {
		params.Set("fields", fmt.Sprintf("%v", v))
	}
	urls := googleapi.ResolveRelative(c.s.BasePath, "apis")
	urls += "?" + params.Encode()
	req, _ := http.NewRequest("GET", urls, body)
	googleapi.SetOpaque(req.URL)
	req.Header.Set("User-Agent", c.s.userAgent())
	if c.ctx_ != nil {
		return ctxhttp.Do(c.ctx_, c.s.client, req)
	}
	return c.s.client.Do(req)
}

func (c *ApisListCall) Do() (*DirectoryList, error) {
	res, err := c.doRequest("json")
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	var ret *DirectoryList
	if err := json.NewDecoder(res.Body).Decode(&ret); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieve the list of APIs supported at this endpoint.",
	//   "httpMethod": "GET",
	//   "id": "discovery.apis.list",
	//   "parameters": {
	//     "name": {
	//       "description": "Only include APIs with the given name.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "preferred": {
	//       "default": "false",
	//       "description": "Return only the preferred version of an API.",
	//       "location": "query",
	//       "type": "boolean"
	//     }
	//   },
	//   "path": "apis",
	//   "response": {
	//     "$ref": "DirectoryList"
	//   }
	// }

}
