// Copyright 2019 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 streetviewpublish provides access to the Street View Publish API.
//
// For product documentation, see: https://developers.google.com/streetview/publish/
//
// Creating a client
//
// Usage example:
//
//   import "google.golang.org/api/streetviewpublish/v1"
//   ...
//   ctx := context.Background()
//   streetviewpublishService, err := streetviewpublish.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:
//
//   streetviewpublishService, err := streetviewpublish.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, ...)
//   streetviewpublishService, err := streetviewpublish.NewService(ctx, option.WithTokenSource(config.TokenSource(ctx, token)))
//
// See https://godoc.org/google.golang.org/api/option/ for details on options.
package streetviewpublish // import "google.golang.org/api/streetviewpublish/v1"

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"
	htransport "google.golang.org/api/transport/http"
)

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

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

// OAuth2 scopes used by this API.
const (
	// Publish and manage your 360 photos on Google Street View
	StreetviewpublishScope = "https://www.googleapis.com/auth/streetviewpublish"
)

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

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

	Photo *PhotoService

	Photos *PhotosService
}

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

func NewPhotoService(s *Service) *PhotoService {
	rs := &PhotoService{s: s}
	return rs
}

type PhotoService struct {
	s *Service
}

func NewPhotosService(s *Service) *PhotosService {
	rs := &PhotosService{s: s}
	return rs
}

type PhotosService struct {
	s *Service
}

// BatchDeletePhotosRequest: Request to delete multiple Photos.
type BatchDeletePhotosRequest struct {
	// PhotoIds: Required. IDs of the Photos. HTTP
	// GET requests require the following syntax for the URL query
	// parameter:
	// `photoIds=<id1>&photoIds=<id2>&...`.
	PhotoIds []string `json:"photoIds,omitempty"`

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

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

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

// BatchDeletePhotosResponse: Response to batch delete of one or
// more
// Photos.
type BatchDeletePhotosResponse struct {
	// Status: The status for the operation to delete a single
	// Photo in the batch request.
	Status []*Status `json:"status,omitempty"`

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

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

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

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

// BatchGetPhotosResponse: Response to batch get of Photos.
type BatchGetPhotosResponse struct {
	// Results: List of results for each individual
	// Photo requested, in the same order as
	// the requests in
	// BatchGetPhotos.
	Results []*PhotoResponse `json:"results,omitempty"`

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

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

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

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

// BatchUpdatePhotosRequest: Request to update the metadata of
// photos.
// Updating the pixels of photos is not supported.
type BatchUpdatePhotosRequest struct {
	// UpdatePhotoRequests: Required. List of
	// UpdatePhotoRequests.
	UpdatePhotoRequests []*UpdatePhotoRequest `json:"updatePhotoRequests,omitempty"`

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

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

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

// BatchUpdatePhotosResponse: Response to batch update of metadata of
// one or more
// Photos.
type BatchUpdatePhotosResponse struct {
	// Results: List of results for each individual
	// Photo updated, in the same order as
	// the request.
	Results []*PhotoResponse `json:"results,omitempty"`

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

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

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

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

// Connection: A connection is the link from a source photo to a
// destination photo.
type Connection struct {
	// Target: Required. The destination of the connection from the
	// containing photo to
	// another photo.
	Target *PhotoId `json:"target,omitempty"`

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

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

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

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

// LatLng: An object representing a latitude/longitude pair. This is
// expressed as a pair
// of doubles representing degrees latitude and degrees longitude.
// Unless
// specified otherwise, this must conform to the
// <a
// href="http://www.unoosa.org/pdf/icg/2012/template/WGS_84.pdf">WGS84
// st
// andard</a>. Values must be within normalized ranges.
type LatLng struct {
	// Latitude: The latitude in degrees. It must be in the range [-90.0,
	// +90.0].
	Latitude float64 `json:"latitude,omitempty"`

	// Longitude: The longitude in degrees. It must be in the range [-180.0,
	// +180.0].
	Longitude float64 `json:"longitude,omitempty"`

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

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

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

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

// Level: Level information containing level number and its
// corresponding name.
type Level struct {
	// Name: Required. A name assigned to this Level, restricted to 3
	// characters.
	// Consider how the elevator buttons would be labeled for this level if
	// there
	// was an elevator.
	Name string `json:"name,omitempty"`

	// Number: Floor number, used for ordering. 0 indicates the ground
	// level, 1 indicates
	// the first level above ground level, -1 indicates the first level
	// under
	// ground level. Non-integer values are OK.
	Number float64 `json:"number,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 *Level) MarshalJSON() ([]byte, error) {
	type NoMethod Level
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

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

// ListPhotosResponse: Response to list all photos that belong to a
// user.
type ListPhotosResponse struct {
	// NextPageToken: Token to retrieve the next page of results, or empty
	// if there are no more
	// results in the list.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// Photos: List of photos. The
	// pageSize field
	// in the request determines the number of items returned.
	Photos []*Photo `json:"photos,omitempty"`

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

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

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

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

// Operation: This resource represents a long-running operation that is
// the result of a
// network API call.
type Operation struct {
	// Done: If the value is `false`, it means the operation is still in
	// progress.
	// If `true`, the operation is completed, and either `error` or
	// `response` is
	// available.
	Done bool `json:"done,omitempty"`

	// Error: The error result of the operation in case of failure or
	// cancellation.
	Error *Status `json:"error,omitempty"`

	// Metadata: Service-specific metadata associated with the operation.
	// It typically
	// contains progress information and common metadata such as create
	// time.
	// Some services might not provide such metadata.  Any method that
	// returns a
	// long-running operation should document the metadata type, if any.
	Metadata googleapi.RawMessage `json:"metadata,omitempty"`

	// Name: The server-assigned name, which is only unique within the same
	// service that
	// originally returns it. If you use the default HTTP mapping,
	// the
	// `name` should be a resource name ending with
	// `operations/{unique_id}`.
	Name string `json:"name,omitempty"`

	// Response: The normal response of the operation in case of success.
	// If the original
	// method returns no data on success, such as `Delete`, the response
	// is
	// `google.protobuf.Empty`.  If the original method is
	// standard
	// `Get`/`Create`/`Update`, the response should be the resource.  For
	// other
	// methods, the response should have the type `XxxResponse`, where
	// `Xxx`
	// is the original method name.  For example, if the original method
	// name
	// is `TakeSnapshot()`, the inferred response type
	// is
	// `TakeSnapshotResponse`.
	Response googleapi.RawMessage `json:"response,omitempty"`

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

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

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

// Photo: Photo is used to store 360 photos along with photo metadata.
type Photo struct {
	// CaptureTime: Absolute time when the photo was captured.
	// When the photo has no exif timestamp, this is used to set a timestamp
	// in
	// the photo metadata.
	CaptureTime string `json:"captureTime,omitempty"`

	// Connections: Connections to other photos. A connection represents the
	// link from this
	// photo to another photo.
	Connections []*Connection `json:"connections,omitempty"`

	// DownloadUrl: Output only. The download URL for the photo bytes. This
	// field is set only
	// when
	// GetPhotoRequest.view
	// is set to
	// PhotoView.INCLUDE_DOWNLOAD_URL.
	DownloadUrl string `json:"downloadUrl,omitempty"`

	// MapsPublishStatus: Output only. Status in Google Maps, whether this
	// photo was published or
	// rejected.
	//
	// Possible values:
	//   "UNSPECIFIED_MAPS_PUBLISH_STATUS" - The status of the photo is
	// unknown.
	//   "PUBLISHED" - The photo is published to the public through Google
	// Maps.
	//   "REJECTED_UNKNOWN" - The photo has been rejected for an unknown
	// reason.
	MapsPublishStatus string `json:"mapsPublishStatus,omitempty"`

	// PhotoId: Required when updating a photo. Output only when creating a
	// photo.
	// Identifier for the photo, which is unique among all photos in
	// Google.
	PhotoId *PhotoId `json:"photoId,omitempty"`

	// Places: Places where this photo belongs.
	Places []*Place `json:"places,omitempty"`

	// Pose: Pose of the photo.
	Pose *Pose `json:"pose,omitempty"`

	// ShareLink: Output only. The share link for the photo.
	ShareLink string `json:"shareLink,omitempty"`

	// ThumbnailUrl: Output only. The thumbnail URL for showing a preview of
	// the given photo.
	ThumbnailUrl string `json:"thumbnailUrl,omitempty"`

	// TransferStatus: Output only. Status of rights transfer on this photo.
	//
	// Possible values:
	//   "TRANSFER_STATUS_UNKNOWN" - The status of this transfer is
	// unspecified.
	//   "NEVER_TRANSFERRED" - This photo has never been in a transfer.
	//   "PENDING" - This photo transfer has been initiated, but the
	// receiver has not yet
	// responded.
	//   "COMPLETED" - The photo transfer has been completed, and this photo
	// has been
	// transferred to the recipient.
	//   "REJECTED" - The recipient rejected this photo transfer.
	//   "EXPIRED" - The photo transfer expired before the recipient took
	// any action.
	//   "CANCELLED" - The sender cancelled this photo transfer.
	//   "RECEIVED_VIA_TRANSFER" - The recipient owns this photo due to a
	// rights transfer.
	TransferStatus string `json:"transferStatus,omitempty"`

	// UploadReference: Required when creating a photo. Input only. The
	// resource URL where the
	// photo bytes are uploaded to.
	UploadReference *UploadRef `json:"uploadReference,omitempty"`

	// ViewCount: Output only. View count of the photo.
	ViewCount int64 `json:"viewCount,omitempty,string"`

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

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

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

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

// PhotoId: Identifier for a Photo.
type PhotoId struct {
	// Id: Required. A unique identifier for a photo.
	Id string `json:"id,omitempty"`

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

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

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

// PhotoResponse: Response payload for a single
// Photo
// in batch operations including
// BatchGetPhotos
// and
// BatchUpdatePhotos.
type PhotoResponse struct {
	// Photo: The Photo resource, if the request
	// was successful.
	Photo *Photo `json:"photo,omitempty"`

	// Status: The status for the operation to get or update a single photo
	// in the batch
	// request.
	Status *Status `json:"status,omitempty"`

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

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

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

// Place: Place metadata for an entity.
type Place struct {
	// LanguageCode: Output-only. The language_code that the name is
	// localized with. This should
	// be the language_code specified in the request, but may be a fallback.
	LanguageCode string `json:"languageCode,omitempty"`

	// Name: Output-only. The name of the place, localized to the
	// language_code.
	Name string `json:"name,omitempty"`

	// PlaceId: Place identifier, as described
	// in
	// https://developers.google.com/places/place-id.
	PlaceId string `json:"placeId,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 *Place) MarshalJSON() ([]byte, error) {
	type NoMethod Place
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Pose: Raw pose measurement for an entity.
type Pose struct {
	// AccuracyMeters: The estimated horizontal accuracy of this pose in
	// meters with 68%
	// confidence (one standard deviation). For example, on Android, this
	// value is
	// available from this
	// method:
	// https://developer.android.com/reference/android/location/Locat
	// ion#getAccuracy().
	// Other platforms have different methods of obtaining similar
	// accuracy
	// estimations.
	AccuracyMeters float64 `json:"accuracyMeters,omitempty"`

	// Altitude: Altitude of the pose in meters above WGS84 ellipsoid.
	// NaN indicates an unmeasured quantity.
	Altitude float64 `json:"altitude,omitempty"`

	// Heading: Compass heading, measured at the center of the photo in
	// degrees clockwise
	// from North. Value must be >=0 and <360.
	// NaN indicates an unmeasured quantity.
	Heading float64 `json:"heading,omitempty"`

	// LatLngPair: Latitude and longitude pair of the pose, as explained
	// here:
	// https://cloud.google.com/datastore/docs/reference/rest/Shared.Ty
	// pes/LatLng
	// When creating a Photo, if the
	// latitude and longitude pair are not provided, the geolocation from
	// the
	// exif header is used. A latitude and longitude pair not provided in
	// the
	// photo or exif header causes the photo process to fail.
	LatLngPair *LatLng `json:"latLngPair,omitempty"`

	// Level: Level (the floor in a building) used to configure vertical
	// navigation.
	Level *Level `json:"level,omitempty"`

	// Pitch: Pitch, measured at the center of the photo in degrees. Value
	// must be >=-90
	// and <= 90. A value of -90 means looking directly down, and a value of
	// 90
	// means looking directly up.
	// NaN indicates an unmeasured quantity.
	Pitch float64 `json:"pitch,omitempty"`

	// Roll: Roll, measured in degrees. Value must be >= 0 and <360. A value
	// of 0
	// means level with the horizon.
	// NaN indicates an unmeasured quantity.
	Roll float64 `json:"roll,omitempty"`

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

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

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

func (s *Pose) UnmarshalJSON(data []byte) error {
	type NoMethod Pose
	var s1 struct {
		AccuracyMeters gensupport.JSONFloat64 `json:"accuracyMeters"`
		Altitude       gensupport.JSONFloat64 `json:"altitude"`
		Heading        gensupport.JSONFloat64 `json:"heading"`
		Pitch          gensupport.JSONFloat64 `json:"pitch"`
		Roll           gensupport.JSONFloat64 `json:"roll"`
		*NoMethod
	}
	s1.NoMethod = (*NoMethod)(s)
	if err := json.Unmarshal(data, &s1); err != nil {
		return err
	}
	s.AccuracyMeters = float64(s1.AccuracyMeters)
	s.Altitude = float64(s1.Altitude)
	s.Heading = float64(s1.Heading)
	s.Pitch = float64(s1.Pitch)
	s.Roll = float64(s1.Roll)
	return nil
}

// Status: The `Status` type defines a logical error model that is
// suitable for
// different programming environments, including REST APIs and RPC APIs.
// It is
// used by [gRPC](https://github.com/grpc). Each `Status` message
// contains
// three pieces of data: error code, error message, and error
// details.
//
// You can find out more about this error model and how to work with it
// in the
// [API Design Guide](https://cloud.google.com/apis/design/errors).
type Status struct {
	// Code: The status code, which should be an enum value of
	// google.rpc.Code.
	Code int64 `json:"code,omitempty"`

	// Details: A list of messages that carry the error details.  There is a
	// common set of
	// message types for APIs to use.
	Details []googleapi.RawMessage `json:"details,omitempty"`

	// Message: A developer-facing error message, which should be in
	// English. Any
	// user-facing error message should be localized and sent in
	// the
	// google.rpc.Status.details field, or localized by the client.
	Message string `json:"message,omitempty"`

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

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

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

// UpdatePhotoRequest: Request to update the metadata of a
// Photo. Updating the pixels of a photo
// is not supported.
type UpdatePhotoRequest struct {
	// Photo: Required. Photo object containing the
	// new metadata.
	Photo *Photo `json:"photo,omitempty"`

	// UpdateMask: Mask that identifies fields on the photo metadata to
	// update.
	// If not present, the old Photo
	// metadata is entirely replaced with the
	// new Photo metadata in this request.
	// The update fails if invalid fields are specified. Multiple fields can
	// be
	// specified in a comma-delimited list.
	//
	// The following fields are valid:
	//
	// * `pose.heading`
	// * `pose.latLngPair`
	// * `pose.pitch`
	// * `pose.roll`
	// * `pose.level`
	// * `pose.altitude`
	// * `connections`
	// * `places`
	//
	//
	// <aside class="note"><b>Note:</b> When
	// updateMask
	// contains repeated fields, the entire set of repeated values get
	// replaced
	// with the new contents. For example, if
	// updateMask
	// contains `connections` and `UpdatePhotoRequest.photo.connections` is
	// empty,
	// all connections are removed.</aside>
	UpdateMask string `json:"updateMask,omitempty"`

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

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

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

// UploadRef: Upload reference for media files.
type UploadRef struct {
	// UploadUrl: Required. An upload reference should be unique for each
	// user. It follows
	// the
	// form:
	// "https://streetviewpublish.googleapis.com/media/user/{account_id
	// }/photo/{upload_reference}"
	UploadUrl string `json:"uploadUrl,omitempty"`

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

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

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

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

// method id "streetviewpublish.photo.create":

type PhotoCreateCall struct {
	s          *Service
	photo      *Photo
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Create: After the client finishes uploading the photo with the
// returned
// UploadRef,
// CreatePhoto
// publishes the uploaded Photo to
// Street View on Google Maps.
//
// Currently, the only way to set heading, pitch, and roll in
// CreatePhoto is
// through the [Photo Sphere
// XMP
// metadata](https://developers.google.com/streetview/spherical-metad
// ata) in
// the photo bytes. CreatePhoto ignores the  `pose.heading`,
// `pose.pitch`,
// `pose.roll`, `pose.altitude`, and `pose.level` fields in Pose.
//
// This method returns the following error codes:
//
// * google.rpc.Code.INVALID_ARGUMENT if the request is malformed or
// if
// the uploaded photo is not a 360 photo.
// * google.rpc.Code.NOT_FOUND if the upload reference does not exist.
// * google.rpc.Code.RESOURCE_EXHAUSTED if the account has reached
// the
// storage limit.
func (r *PhotoService) Create(photo *Photo) *PhotoCreateCall {
	c := &PhotoCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.photo = photo
	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 *PhotoCreateCall) Fields(s ...googleapi.Field) *PhotoCreateCall {
	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 *PhotoCreateCall) Context(ctx context.Context) *PhotoCreateCall {
	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 *PhotoCreateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *PhotoCreateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20190905")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.photo)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/photo")
	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 "streetviewpublish.photo.create" call.
// Exactly one of *Photo or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Photo.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 *PhotoCreateCall) Do(opts ...googleapi.CallOption) (*Photo, 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 := &Photo{
		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": "After the client finishes uploading the photo with the returned\nUploadRef,\nCreatePhoto\npublishes the uploaded Photo to\nStreet View on Google Maps.\n\nCurrently, the only way to set heading, pitch, and roll in CreatePhoto is\nthrough the [Photo Sphere XMP\nmetadata](https://developers.google.com/streetview/spherical-metadata) in\nthe photo bytes. CreatePhoto ignores the  `pose.heading`, `pose.pitch`,\n`pose.roll`, `pose.altitude`, and `pose.level` fields in Pose.\n\nThis method returns the following error codes:\n\n* google.rpc.Code.INVALID_ARGUMENT if the request is malformed or if\nthe uploaded photo is not a 360 photo.\n* google.rpc.Code.NOT_FOUND if the upload reference does not exist.\n* google.rpc.Code.RESOURCE_EXHAUSTED if the account has reached the\nstorage limit.",
	//   "flatPath": "v1/photo",
	//   "httpMethod": "POST",
	//   "id": "streetviewpublish.photo.create",
	//   "parameterOrder": [],
	//   "parameters": {},
	//   "path": "v1/photo",
	//   "request": {
	//     "$ref": "Photo"
	//   },
	//   "response": {
	//     "$ref": "Photo"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/streetviewpublish"
	//   ]
	// }

}

// method id "streetviewpublish.photo.delete":

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

// Delete: Deletes a Photo and its metadata.
//
// This method returns the following error codes:
//
// * google.rpc.Code.PERMISSION_DENIED if the requesting user did
// not
// create the requested photo.
// * google.rpc.Code.NOT_FOUND if the photo ID does not exist.
func (r *PhotoService) Delete(photoId string) *PhotoDeleteCall {
	c := &PhotoDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.photoId = photoId
	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 *PhotoDeleteCall) Fields(s ...googleapi.Field) *PhotoDeleteCall {
	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 *PhotoDeleteCall) Context(ctx context.Context) *PhotoDeleteCall {
	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 *PhotoDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *PhotoDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20190905")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/photo/{photoId}")
	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{
		"photoId": c.photoId,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "streetviewpublish.photo.delete" call.
// Exactly one of *Empty or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Empty.ServerResponse.Header or (if a response was returned at all)
// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to
// check whether the returned error was because http.StatusNotModified
// was returned.
func (c *PhotoDeleteCall) Do(opts ...googleapi.CallOption) (*Empty, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Empty{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Deletes a Photo and its metadata.\n\nThis method returns the following error codes:\n\n* google.rpc.Code.PERMISSION_DENIED if the requesting user did not\ncreate the requested photo.\n* google.rpc.Code.NOT_FOUND if the photo ID does not exist.",
	//   "flatPath": "v1/photo/{photoId}",
	//   "httpMethod": "DELETE",
	//   "id": "streetviewpublish.photo.delete",
	//   "parameterOrder": [
	//     "photoId"
	//   ],
	//   "parameters": {
	//     "photoId": {
	//       "description": "Required. ID of the Photo.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/photo/{photoId}",
	//   "response": {
	//     "$ref": "Empty"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/streetviewpublish"
	//   ]
	// }

}

// method id "streetviewpublish.photo.get":

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

// Get: Gets the metadata of the specified
// Photo.
//
// This method returns the following error codes:
//
// * google.rpc.Code.PERMISSION_DENIED if the requesting user did
// not
// create the requested Photo.
// * google.rpc.Code.NOT_FOUND if the requested
// Photo does not exist.
// * google.rpc.Code.UNAVAILABLE if the requested
// Photo is still being indexed.
func (r *PhotoService) Get(photoId string) *PhotoGetCall {
	c := &PhotoGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.photoId = photoId
	return c
}

// LanguageCode sets the optional parameter "languageCode": The BCP-47
// language code, such as "en-US" or "sr-Latn". For more
// information,
// see
// http://www.unicode.org/reports/tr35/#Unicode_locale_identifier.
// If
//  language_code is unspecified, the user's language preference for
// Google
// services is used.
func (c *PhotoGetCall) LanguageCode(languageCode string) *PhotoGetCall {
	c.urlParams_.Set("languageCode", languageCode)
	return c
}

// View sets the optional parameter "view": Specifies if a download URL
// for the photo bytes should be returned in the
// Photo response.
//
// Possible values:
//   "BASIC"
//   "INCLUDE_DOWNLOAD_URL"
func (c *PhotoGetCall) View(view string) *PhotoGetCall {
	c.urlParams_.Set("view", view)
	return c
}

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

func (c *PhotoGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20190905")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/photo/{photoId}")
	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{
		"photoId": c.photoId,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "streetviewpublish.photo.get" call.
// Exactly one of *Photo or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Photo.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 *PhotoGetCall) Do(opts ...googleapi.CallOption) (*Photo, 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 := &Photo{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Gets the metadata of the specified\nPhoto.\n\nThis method returns the following error codes:\n\n* google.rpc.Code.PERMISSION_DENIED if the requesting user did not\ncreate the requested Photo.\n* google.rpc.Code.NOT_FOUND if the requested\nPhoto does not exist.\n* google.rpc.Code.UNAVAILABLE if the requested\nPhoto is still being indexed.",
	//   "flatPath": "v1/photo/{photoId}",
	//   "httpMethod": "GET",
	//   "id": "streetviewpublish.photo.get",
	//   "parameterOrder": [
	//     "photoId"
	//   ],
	//   "parameters": {
	//     "languageCode": {
	//       "description": "The BCP-47 language code, such as \"en-US\" or \"sr-Latn\". For more\ninformation, see\nhttp://www.unicode.org/reports/tr35/#Unicode_locale_identifier.\nIf language_code is unspecified, the user's language preference for Google\nservices is used.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "photoId": {
	//       "description": "Required. ID of the Photo.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "view": {
	//       "description": "Specifies if a download URL for the photo bytes should be returned in the\nPhoto response.",
	//       "enum": [
	//         "BASIC",
	//         "INCLUDE_DOWNLOAD_URL"
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/photo/{photoId}",
	//   "response": {
	//     "$ref": "Photo"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/streetviewpublish"
	//   ]
	// }

}

// method id "streetviewpublish.photo.startUpload":

type PhotoStartUploadCall struct {
	s          *Service
	empty      *Empty
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// StartUpload: Creates an upload session to start uploading photo
// bytes.  The method uses
// the upload URL of the returned
// UploadRef to upload the bytes for
// the Photo.
//
// In addition to the photo requirements shown
// in
// https://support.google.com/maps/answer/7012050?hl=en&ref_topic=6275
// 604,
// the photo must meet the following requirements:
//
// * Photo Sphere XMP metadata must be included in the photo medadata.
// See
// https://developers.google.com/streetview/spherical-metadata for
// the
// required fields.
// * The pixel size of the photo must meet the size requirements listed
// in
// https://support.google.com/maps/answer/7012050?hl=en&ref_topic=6275
// 604, and
// the photo must be a full 360 horizontally.
//
// After the upload completes, the method uses
// UploadRef with
// CreatePhoto
// to create the Photo object entry.
func (r *PhotoService) StartUpload(empty *Empty) *PhotoStartUploadCall {
	c := &PhotoStartUploadCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.empty = empty
	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 *PhotoStartUploadCall) Fields(s ...googleapi.Field) *PhotoStartUploadCall {
	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 *PhotoStartUploadCall) Context(ctx context.Context) *PhotoStartUploadCall {
	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 *PhotoStartUploadCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *PhotoStartUploadCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20190905")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.empty)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/photo:startUpload")
	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 "streetviewpublish.photo.startUpload" call.
// Exactly one of *UploadRef or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *UploadRef.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 *PhotoStartUploadCall) Do(opts ...googleapi.CallOption) (*UploadRef, 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 := &UploadRef{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Creates an upload session to start uploading photo bytes.  The method uses\nthe upload URL of the returned\nUploadRef to upload the bytes for\nthe Photo.\n\nIn addition to the photo requirements shown in\nhttps://support.google.com/maps/answer/7012050?hl=en\u0026ref_topic=6275604,\nthe photo must meet the following requirements:\n\n* Photo Sphere XMP metadata must be included in the photo medadata. See\nhttps://developers.google.com/streetview/spherical-metadata for the\nrequired fields.\n* The pixel size of the photo must meet the size requirements listed in\nhttps://support.google.com/maps/answer/7012050?hl=en\u0026ref_topic=6275604, and\nthe photo must be a full 360 horizontally.\n\nAfter the upload completes, the method uses\nUploadRef with\nCreatePhoto\nto create the Photo object entry.",
	//   "flatPath": "v1/photo:startUpload",
	//   "httpMethod": "POST",
	//   "id": "streetviewpublish.photo.startUpload",
	//   "parameterOrder": [],
	//   "parameters": {},
	//   "path": "v1/photo:startUpload",
	//   "request": {
	//     "$ref": "Empty"
	//   },
	//   "response": {
	//     "$ref": "UploadRef"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/streetviewpublish"
	//   ]
	// }

}

// method id "streetviewpublish.photo.update":

type PhotoUpdateCall struct {
	s          *Service
	id         string
	photo      *Photo
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Update: Updates the metadata of a Photo, such
// as pose, place association, connections, etc. Changing the pixels of
// a
// photo is not supported.
//
// Only the fields specified in the
// updateMask
// field are used. If `updateMask` is not present, the update applies to
// all
// fields.
//
// This method returns the following error codes:
//
// * google.rpc.Code.PERMISSION_DENIED if the requesting user did
// not
// create the requested photo.
// * google.rpc.Code.INVALID_ARGUMENT if the request is malformed.
// * google.rpc.Code.NOT_FOUND if the requested photo does not exist.
// * google.rpc.Code.UNAVAILABLE if the requested
// Photo is still being indexed.
func (r *PhotoService) Update(id string, photo *Photo) *PhotoUpdateCall {
	c := &PhotoUpdateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.id = id
	c.photo = photo
	return c
}

// UpdateMask sets the optional parameter "updateMask": Mask that
// identifies fields on the photo metadata to update.
// If not present, the old Photo
// metadata is entirely replaced with the
// new Photo metadata in this request.
// The update fails if invalid fields are specified. Multiple fields can
// be
// specified in a comma-delimited list.
//
// The following fields are valid:
//
// * `pose.heading`
// * `pose.latLngPair`
// * `pose.pitch`
// * `pose.roll`
// * `pose.level`
// * `pose.altitude`
// * `connections`
// * `places`
//
//
// <aside class="note"><b>Note:</b> When
// updateMask
// contains repeated fields, the entire set of repeated values get
// replaced
// with the new contents. For example, if
// updateMask
// contains `connections` and `UpdatePhotoRequest.photo.connections` is
// empty,
// all connections are removed.</aside>
func (c *PhotoUpdateCall) UpdateMask(updateMask string) *PhotoUpdateCall {
	c.urlParams_.Set("updateMask", updateMask)
	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 *PhotoUpdateCall) Fields(s ...googleapi.Field) *PhotoUpdateCall {
	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 *PhotoUpdateCall) Context(ctx context.Context) *PhotoUpdateCall {
	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 *PhotoUpdateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *PhotoUpdateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20190905")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.photo)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/photo/{id}")
	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{
		"id": c.id,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "streetviewpublish.photo.update" call.
// Exactly one of *Photo or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Photo.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 *PhotoUpdateCall) Do(opts ...googleapi.CallOption) (*Photo, 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 := &Photo{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Updates the metadata of a Photo, such\nas pose, place association, connections, etc. Changing the pixels of a\nphoto is not supported.\n\nOnly the fields specified in the\nupdateMask\nfield are used. If `updateMask` is not present, the update applies to all\nfields.\n\nThis method returns the following error codes:\n\n* google.rpc.Code.PERMISSION_DENIED if the requesting user did not\ncreate the requested photo.\n* google.rpc.Code.INVALID_ARGUMENT if the request is malformed.\n* google.rpc.Code.NOT_FOUND if the requested photo does not exist.\n* google.rpc.Code.UNAVAILABLE if the requested\nPhoto is still being indexed.",
	//   "flatPath": "v1/photo/{id}",
	//   "httpMethod": "PUT",
	//   "id": "streetviewpublish.photo.update",
	//   "parameterOrder": [
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "Required. A unique identifier for a photo.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "updateMask": {
	//       "description": "Mask that identifies fields on the photo metadata to update.\nIf not present, the old Photo\nmetadata is entirely replaced with the\nnew Photo metadata in this request.\nThe update fails if invalid fields are specified. Multiple fields can be\nspecified in a comma-delimited list.\n\nThe following fields are valid:\n\n* `pose.heading`\n* `pose.latLngPair`\n* `pose.pitch`\n* `pose.roll`\n* `pose.level`\n* `pose.altitude`\n* `connections`\n* `places`\n\n\n\u003caside class=\"note\"\u003e\u003cb\u003eNote:\u003c/b\u003e When\nupdateMask\ncontains repeated fields, the entire set of repeated values get replaced\nwith the new contents. For example, if\nupdateMask\ncontains `connections` and `UpdatePhotoRequest.photo.connections` is empty,\nall connections are removed.\u003c/aside\u003e",
	//       "format": "google-fieldmask",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/photo/{id}",
	//   "request": {
	//     "$ref": "Photo"
	//   },
	//   "response": {
	//     "$ref": "Photo"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/streetviewpublish"
	//   ]
	// }

}

// method id "streetviewpublish.photos.batchDelete":

type PhotosBatchDeleteCall struct {
	s                        *Service
	batchdeletephotosrequest *BatchDeletePhotosRequest
	urlParams_               gensupport.URLParams
	ctx_                     context.Context
	header_                  http.Header
}

// BatchDelete: Deletes a list of Photos and their
// metadata.
//
// Note that if
// BatchDeletePhotos
// fails, either critical fields are missing or there is an
// authentication
// error. Even if
// BatchDeletePhotos
// succeeds, individual photos in the batch may have failures.
// These failures are specified in
// each
// PhotoResponse.status
// in
// BatchDeletePhotosResponse.results.
// See
// De
// letePhoto
// for specific failures that can occur per photo.
func (r *PhotosService) BatchDelete(batchdeletephotosrequest *BatchDeletePhotosRequest) *PhotosBatchDeleteCall {
	c := &PhotosBatchDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.batchdeletephotosrequest = batchdeletephotosrequest
	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 *PhotosBatchDeleteCall) Fields(s ...googleapi.Field) *PhotosBatchDeleteCall {
	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 *PhotosBatchDeleteCall) Context(ctx context.Context) *PhotosBatchDeleteCall {
	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 *PhotosBatchDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *PhotosBatchDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20190905")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.batchdeletephotosrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/photos:batchDelete")
	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 "streetviewpublish.photos.batchDelete" call.
// Exactly one of *BatchDeletePhotosResponse or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *BatchDeletePhotosResponse.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 *PhotosBatchDeleteCall) Do(opts ...googleapi.CallOption) (*BatchDeletePhotosResponse, 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 := &BatchDeletePhotosResponse{
		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": "Deletes a list of Photos and their\nmetadata.\n\nNote that if\nBatchDeletePhotos\nfails, either critical fields are missing or there is an authentication\nerror. Even if\nBatchDeletePhotos\nsucceeds, individual photos in the batch may have failures.\nThese failures are specified in each\nPhotoResponse.status\nin\nBatchDeletePhotosResponse.results.\nSee\nDeletePhoto\nfor specific failures that can occur per photo.",
	//   "flatPath": "v1/photos:batchDelete",
	//   "httpMethod": "POST",
	//   "id": "streetviewpublish.photos.batchDelete",
	//   "parameterOrder": [],
	//   "parameters": {},
	//   "path": "v1/photos:batchDelete",
	//   "request": {
	//     "$ref": "BatchDeletePhotosRequest"
	//   },
	//   "response": {
	//     "$ref": "BatchDeletePhotosResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/streetviewpublish"
	//   ]
	// }

}

// method id "streetviewpublish.photos.batchGet":

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

// BatchGet: Gets the metadata of the specified
// Photo batch.
//
// Note that if
// BatchGetPhotos
// fails, either critical fields are missing or there is an
// authentication
// error. Even if
// BatchGetPhotos
// succeeds, individual photos in the batch may have failures.
// These failures are specified in
// each
// PhotoResponse.status
// in
// BatchGetPhotosResponse.results.
// See
// GetPh
// oto
// for specific failures that can occur per photo.
func (r *PhotosService) BatchGet() *PhotosBatchGetCall {
	c := &PhotosBatchGetCall{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". For more
// information,
// see
// http://www.unicode.org/reports/tr35/#Unicode_locale_identifier.
// If
//  language_code is unspecified, the user's language preference for
// Google
// services is used.
func (c *PhotosBatchGetCall) LanguageCode(languageCode string) *PhotosBatchGetCall {
	c.urlParams_.Set("languageCode", languageCode)
	return c
}

// PhotoIds sets the optional parameter "photoIds": Required. IDs of the
// Photos. For HTTP
// GET requests, the URL query parameter should
// be
// `photoIds=<id1>&photoIds=<id2>&...`.
func (c *PhotosBatchGetCall) PhotoIds(photoIds ...string) *PhotosBatchGetCall {
	c.urlParams_.SetMulti("photoIds", append([]string{}, photoIds...))
	return c
}

// View sets the optional parameter "view": Specifies if a download URL
// for the photo bytes should be returned in the
// Photo response.
//
// Possible values:
//   "BASIC"
//   "INCLUDE_DOWNLOAD_URL"
func (c *PhotosBatchGetCall) View(view string) *PhotosBatchGetCall {
	c.urlParams_.Set("view", view)
	return c
}

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

func (c *PhotosBatchGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20190905")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/photos:batchGet")
	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 "streetviewpublish.photos.batchGet" call.
// Exactly one of *BatchGetPhotosResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *BatchGetPhotosResponse.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 *PhotosBatchGetCall) Do(opts ...googleapi.CallOption) (*BatchGetPhotosResponse, 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 := &BatchGetPhotosResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Gets the metadata of the specified\nPhoto batch.\n\nNote that if\nBatchGetPhotos\nfails, either critical fields are missing or there is an authentication\nerror. Even if\nBatchGetPhotos\nsucceeds, individual photos in the batch may have failures.\nThese failures are specified in each\nPhotoResponse.status\nin\nBatchGetPhotosResponse.results.\nSee\nGetPhoto\nfor specific failures that can occur per photo.",
	//   "flatPath": "v1/photos:batchGet",
	//   "httpMethod": "GET",
	//   "id": "streetviewpublish.photos.batchGet",
	//   "parameterOrder": [],
	//   "parameters": {
	//     "languageCode": {
	//       "description": "The BCP-47 language code, such as \"en-US\" or \"sr-Latn\". For more\ninformation, see\nhttp://www.unicode.org/reports/tr35/#Unicode_locale_identifier.\nIf language_code is unspecified, the user's language preference for Google\nservices is used.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "photoIds": {
	//       "description": "Required. IDs of the Photos. For HTTP\nGET requests, the URL query parameter should be\n`photoIds=\u003cid1\u003e\u0026photoIds=\u003cid2\u003e\u0026...`.",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "view": {
	//       "description": "Specifies if a download URL for the photo bytes should be returned in the\nPhoto response.",
	//       "enum": [
	//         "BASIC",
	//         "INCLUDE_DOWNLOAD_URL"
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/photos:batchGet",
	//   "response": {
	//     "$ref": "BatchGetPhotosResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/streetviewpublish"
	//   ]
	// }

}

// method id "streetviewpublish.photos.batchUpdate":

type PhotosBatchUpdateCall struct {
	s                        *Service
	batchupdatephotosrequest *BatchUpdatePhotosRequest
	urlParams_               gensupport.URLParams
	ctx_                     context.Context
	header_                  http.Header
}

// BatchUpdate: Updates the metadata of Photos, such
// as pose, place association, connections, etc. Changing the pixels of
// photos
// is not supported.
//
// Note that if
// BatchUpdatePhotos
// fails, either critical fields are missing or there is an
// authentication
// error. Even if
// BatchUpdatePhotos
// succeeds, individual photos in the batch may have failures.
// These failures are specified in
// each
// PhotoResponse.status
// in
// BatchUpdatePhotosResponse.results.
// See
// Up
// datePhoto
// for specific failures that can occur per photo.
//
// Only the fields specified in
// updateMask
// field are used. If `updateMask` is not present, the update applies to
// all
// fields.
//
// The number of
// UpdatePhotoRequest
// messages in a
// BatchUpdatePhotosRequest
// must not exceed 20.
//
// <aside class="note"><b>Note:</b> To
// update
// Pose.altitude,
// Pose.latLngPair has to be
// filled as well. Otherwise, the request will fail.</aside>
func (r *PhotosService) BatchUpdate(batchupdatephotosrequest *BatchUpdatePhotosRequest) *PhotosBatchUpdateCall {
	c := &PhotosBatchUpdateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.batchupdatephotosrequest = batchupdatephotosrequest
	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 *PhotosBatchUpdateCall) Fields(s ...googleapi.Field) *PhotosBatchUpdateCall {
	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 *PhotosBatchUpdateCall) Context(ctx context.Context) *PhotosBatchUpdateCall {
	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 *PhotosBatchUpdateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *PhotosBatchUpdateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20190905")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.batchupdatephotosrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/photos:batchUpdate")
	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 "streetviewpublish.photos.batchUpdate" call.
// Exactly one of *BatchUpdatePhotosResponse or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *BatchUpdatePhotosResponse.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 *PhotosBatchUpdateCall) Do(opts ...googleapi.CallOption) (*BatchUpdatePhotosResponse, 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 := &BatchUpdatePhotosResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Updates the metadata of Photos, such\nas pose, place association, connections, etc. Changing the pixels of photos\nis not supported.\n\nNote that if\nBatchUpdatePhotos\nfails, either critical fields are missing or there is an authentication\nerror. Even if\nBatchUpdatePhotos\nsucceeds, individual photos in the batch may have failures.\nThese failures are specified in each\nPhotoResponse.status\nin\nBatchUpdatePhotosResponse.results.\nSee\nUpdatePhoto\nfor specific failures that can occur per photo.\n\nOnly the fields specified in\nupdateMask\nfield are used. If `updateMask` is not present, the update applies to all\nfields.\n\nThe number of\nUpdatePhotoRequest\nmessages in a\nBatchUpdatePhotosRequest\nmust not exceed 20.\n\n\u003caside class=\"note\"\u003e\u003cb\u003eNote:\u003c/b\u003e To update\nPose.altitude,\nPose.latLngPair has to be\nfilled as well. Otherwise, the request will fail.\u003c/aside\u003e",
	//   "flatPath": "v1/photos:batchUpdate",
	//   "httpMethod": "POST",
	//   "id": "streetviewpublish.photos.batchUpdate",
	//   "parameterOrder": [],
	//   "parameters": {},
	//   "path": "v1/photos:batchUpdate",
	//   "request": {
	//     "$ref": "BatchUpdatePhotosRequest"
	//   },
	//   "response": {
	//     "$ref": "BatchUpdatePhotosResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/streetviewpublish"
	//   ]
	// }

}

// method id "streetviewpublish.photos.list":

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

// List: Lists all the Photos that belong to
// the user.
//
// <aside class="note"><b>Note:</b> Recently created photos that are
// still
// being indexed are not returned in the response.</aside>
func (r *PhotosService) List() *PhotosListCall {
	c := &PhotosListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	return c
}

// Filter sets the optional parameter "filter": The filter expression.
// For example: `placeId=ChIJj61dQgK6j4AR4GeTYWZsKWw`.
//
// The only filter supported at the moment is `placeId`.
func (c *PhotosListCall) Filter(filter string) *PhotosListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// LanguageCode sets the optional parameter "languageCode": The BCP-47
// language code, such as "en-US" or "sr-Latn". For more
// information,
// see
// http://www.unicode.org/reports/tr35/#Unicode_locale_identifier.
// If
//  language_code is unspecified, the user's language preference for
// Google
// services is used.
func (c *PhotosListCall) LanguageCode(languageCode string) *PhotosListCall {
	c.urlParams_.Set("languageCode", languageCode)
	return c
}

// PageSize sets the optional parameter "pageSize": The maximum number
// of photos to return.
// `pageSize` must be non-negative. If `pageSize` is zero or is not
// provided,
// the default page size of 100 is used.
// The number of photos returned in the response may be less than
// `pageSize`
// if the number of photos that belong to the user is less than
// `pageSize`.
func (c *PhotosListCall) PageSize(pageSize int64) *PhotosListCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken":
// The
// nextPageToken
// value returned from a previous
// ListPhotos
// request, if any.
func (c *PhotosListCall) PageToken(pageToken string) *PhotosListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// View sets the optional parameter "view": Specifies if a download URL
// for the photos bytes should be returned in the
// Photos response.
//
// Possible values:
//   "BASIC"
//   "INCLUDE_DOWNLOAD_URL"
func (c *PhotosListCall) View(view string) *PhotosListCall {
	c.urlParams_.Set("view", view)
	return c
}

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

func (c *PhotosListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20190905")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/photos")
	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 "streetviewpublish.photos.list" call.
// Exactly one of *ListPhotosResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *ListPhotosResponse.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 *PhotosListCall) Do(opts ...googleapi.CallOption) (*ListPhotosResponse, 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 := &ListPhotosResponse{
		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": "Lists all the Photos that belong to\nthe user.\n\n\u003caside class=\"note\"\u003e\u003cb\u003eNote:\u003c/b\u003e Recently created photos that are still\nbeing indexed are not returned in the response.\u003c/aside\u003e",
	//   "flatPath": "v1/photos",
	//   "httpMethod": "GET",
	//   "id": "streetviewpublish.photos.list",
	//   "parameterOrder": [],
	//   "parameters": {
	//     "filter": {
	//       "description": "The filter expression. For example: `placeId=ChIJj61dQgK6j4AR4GeTYWZsKWw`.\n\nThe only filter supported at the moment is `placeId`.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "languageCode": {
	//       "description": "The BCP-47 language code, such as \"en-US\" or \"sr-Latn\". For more\ninformation, see\nhttp://www.unicode.org/reports/tr35/#Unicode_locale_identifier.\nIf language_code is unspecified, the user's language preference for Google\nservices is used.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageSize": {
	//       "description": "The maximum number of photos to return.\n`pageSize` must be non-negative. If `pageSize` is zero or is not provided,\nthe default page size of 100 is used.\nThe number of photos returned in the response may be less than `pageSize`\nif the number of photos that belong to the user is less than `pageSize`.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "The\nnextPageToken\nvalue returned from a previous\nListPhotos\nrequest, if any.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "view": {
	//       "description": "Specifies if a download URL for the photos bytes should be returned in the\nPhotos response.",
	//       "enum": [
	//         "BASIC",
	//         "INCLUDE_DOWNLOAD_URL"
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/photos",
	//   "response": {
	//     "$ref": "ListPhotosResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/streetviewpublish"
	//   ]
	// }

}

// 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 *PhotosListCall) Pages(ctx context.Context, f func(*ListPhotosResponse) 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)
	}
}
