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

// Code generated file. DO NOT EDIT.

// Package proximitybeacon provides access to the Proximity Beacon API.
//
// For product documentation, see: https://developers.google.com/beacons/proximity/
//
// Creating a client
//
// Usage example:
//
//   import "google.golang.org/api/proximitybeacon/v1beta1"
//   ...
//   ctx := context.Background()
//   proximitybeaconService, err := proximitybeacon.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:
//
//   proximitybeaconService, err := proximitybeacon.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, ...)
//   proximitybeaconService, err := proximitybeacon.NewService(ctx, option.WithTokenSource(config.TokenSource(ctx, token)))
//
// See https://godoc.org/google.golang.org/api/option/ for details on options.
package proximitybeacon // import "google.golang.org/api/proximitybeacon/v1beta1"

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

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

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

const apiId = "proximitybeacon:v1beta1"
const apiName = "proximitybeacon"
const apiVersion = "v1beta1"
const basePath = "https://proximitybeacon.googleapis.com/"

// OAuth2 scopes used by this API.
const (
	// View and modify your beacons
	UserlocationBeaconRegistryScope = "https://www.googleapis.com/auth/userlocation.beacon.registry"
)

// NewService creates a new Service.
func NewService(ctx context.Context, opts ...option.ClientOption) (*Service, error) {
	scopesOption := option.WithScopes(
		"https://www.googleapis.com/auth/userlocation.beacon.registry",
	)
	// NOTE: prepend, so we don't override user-specified scopes.
	opts = append([]option.ClientOption{scopesOption}, opts...)
	opts = append(opts, internaloption.WithDefaultEndpoint(basePath))
	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.Beaconinfo = NewBeaconinfoService(s)
	s.Beacons = NewBeaconsService(s)
	s.Namespaces = NewNamespacesService(s)
	s.V1beta1 = NewV1beta1Service(s)
	return s, nil
}

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

	Beaconinfo *BeaconinfoService

	Beacons *BeaconsService

	Namespaces *NamespacesService

	V1beta1 *V1beta1Service
}

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

func NewBeaconinfoService(s *Service) *BeaconinfoService {
	rs := &BeaconinfoService{s: s}
	return rs
}

type BeaconinfoService struct {
	s *Service
}

func NewBeaconsService(s *Service) *BeaconsService {
	rs := &BeaconsService{s: s}
	rs.Attachments = NewBeaconsAttachmentsService(s)
	rs.Diagnostics = NewBeaconsDiagnosticsService(s)
	return rs
}

type BeaconsService struct {
	s *Service

	Attachments *BeaconsAttachmentsService

	Diagnostics *BeaconsDiagnosticsService
}

func NewBeaconsAttachmentsService(s *Service) *BeaconsAttachmentsService {
	rs := &BeaconsAttachmentsService{s: s}
	return rs
}

type BeaconsAttachmentsService struct {
	s *Service
}

func NewBeaconsDiagnosticsService(s *Service) *BeaconsDiagnosticsService {
	rs := &BeaconsDiagnosticsService{s: s}
	return rs
}

type BeaconsDiagnosticsService struct {
	s *Service
}

func NewNamespacesService(s *Service) *NamespacesService {
	rs := &NamespacesService{s: s}
	return rs
}

type NamespacesService struct {
	s *Service
}

func NewV1beta1Service(s *Service) *V1beta1Service {
	rs := &V1beta1Service{s: s}
	return rs
}

type V1beta1Service struct {
	s *Service
}

// AdvertisedId: Defines a unique identifier of a beacon as broadcast by
// the device.
type AdvertisedId struct {
	// Id: The actual beacon identifier, as broadcast by the beacon
	// hardware. Must
	// be
	// [base64](http://tools.ietf.org/html/rfc4648#section-4) encoded in
	// HTTP
	// requests, and will be so encoded (with padding) in responses. The
	// base64
	// encoding should be of the binary byte-stream and not any textual
	// (such as
	// hex) representation thereof.
	// Required.
	Id string `json:"id,omitempty"`

	// Type: Specifies the identifier type.
	// Required.
	//
	// Possible values:
	//   "TYPE_UNSPECIFIED" - Do not use this value.
	//   "EDDYSTONE" - Eddystone, an open beacon format that supports
	// Android and iOS
	// devices
	// https://github.com/google/eddystone/wiki/Beacon-Specification
	//   "IBEACON" - Apple iBeacon compatible beacon
	//   "ALTBEACON" - See http://altbeacon.org and/or
	// https://github.com/AltBeacon/spec.
	//   "EDDYSTONE_EID" - Eddystone Ephemeral ID
	Type string `json:"type,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 *AdvertisedId) MarshalJSON() ([]byte, error) {
	type NoMethod AdvertisedId
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// AttachmentInfo: A subset of attachment information served via
// the
// `beaconinfo.getforobserved` method, used when your users encounter
// your
// beacons.
type AttachmentInfo struct {
	// Data: An opaque data container for client-provided data.
	Data string `json:"data,omitempty"`

	// MaxDistanceMeters: The distance away from the beacon at which this
	// attachment should be
	// delivered to a mobile app.
	//
	// Setting this to a value greater than zero indicates that the app
	// should
	// behave as if the beacon is "seen" when the mobile device is less than
	// this
	// distance away from the beacon.
	//
	// Different attachments on the same beacon can have different max
	// distances.
	//
	// Note that even though this value is expressed with fractional
	// meter
	// precision, real-world behavior is likley to be much less precise than
	// one
	// meter, due to the nature of current Bluetooth radio
	// technology.
	//
	// Optional. When not set or zero, the attachment should be delivered at
	// the
	// beacon's outer limit of detection.
	MaxDistanceMeters float64 `json:"maxDistanceMeters,omitempty"`

	// NamespacedType: Specifies what kind of attachment this is. Tells a
	// client how to
	// interpret the `data` field. Format is <var>namespace/type</var>,
	// for
	// example <code>scrupulous-wombat-12345/welcome-message</code>
	NamespacedType string `json:"namespacedType,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Data") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// 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. "Data") 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 *AttachmentInfo) MarshalJSON() ([]byte, error) {
	type NoMethod AttachmentInfo
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

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

// Beacon: Details of a beacon device.
type Beacon struct {
	// AdvertisedId: The identifier of a beacon as advertised by it. This
	// field must be
	// populated when registering. It may be empty when updating a
	// beacon
	// record because it is ignored in updates.
	//
	// When registering a beacon that broadcasts Eddystone-EID, this
	// field
	// should contain a "stable" Eddystone-UID that identifies the beacon
	// and
	// links it to its attachments. The stable Eddystone-UID is only used
	// for
	// administering the beacon.
	AdvertisedId *AdvertisedId `json:"advertisedId,omitempty"`

	// BeaconName: Resource name of this beacon. A beacon name has the
	// format
	// "beacons/N!beaconId" where the beaconId is the base16 ID broadcast
	// by
	// the beacon and N is a code for the beacon's type. Possible values
	// are
	// `3` for Eddystone, `1` for iBeacon, or `5` for AltBeacon.
	//
	// This field must be left empty when registering. After reading a
	// beacon,
	// clients can use the name for future operations.
	BeaconName string `json:"beaconName,omitempty"`

	// Description: Free text used to identify and describe the beacon.
	// Maximum length 140
	// characters.
	// Optional.
	Description string `json:"description,omitempty"`

	// EphemeralIdRegistration: Write-only registration parameters for
	// beacons using Eddystone-EID
	// (remotely resolved ephemeral ID) format. This information will not
	// be
	// populated in API responses. When submitting this data, the
	// `advertised_id`
	// field must contain an ID of type Eddystone-UID. Any other ID type
	// will
	// result in an error.
	EphemeralIdRegistration *EphemeralIdRegistration `json:"ephemeralIdRegistration,omitempty"`

	// ExpectedStability: Expected location stability. This is set when the
	// beacon is registered or
	// updated, not automatically detected in any way.
	// Optional.
	//
	// Possible values:
	//   "STABILITY_UNSPECIFIED" - Do not use this value.
	//   "STABLE" - Not expected to move, for example a store's front door.
	//   "PORTABLE" - Usually stable but may move rarely, usually within a
	// single place,
	// for example a store display.
	//   "MOBILE" - Moves frequently, for example a personal item or food
	// truck.
	//   "ROVING" - Moves continuously in service, for example a bus or
	// train.
	ExpectedStability string `json:"expectedStability,omitempty"`

	// IndoorLevel: The indoor level information for this beacon, if known.
	// As returned by the
	// Google Maps API.
	// Optional.
	IndoorLevel *IndoorLevel `json:"indoorLevel,omitempty"`

	// LatLng: The location of the beacon, expressed as a latitude and
	// longitude pair.
	// This location is given when the beacon is registered or updated. It
	// does
	// not necessarily indicate the actual current location of the
	// beacon.
	// Optional.
	LatLng *LatLng `json:"latLng,omitempty"`

	// PlaceId: The [Google Places API](/places/place-id) Place ID of the
	// place where
	// the beacon is deployed. This is given when the beacon is registered
	// or
	// updated, not automatically detected in any way.
	// Optional.
	PlaceId string `json:"placeId,omitempty"`

	// Properties: Properties of the beacon device, for example battery type
	// or firmware
	// version.
	// Optional.
	Properties map[string]string `json:"properties,omitempty"`

	// ProvisioningKey: Some beacons may require a user to provide an
	// authorization key before
	// changing any of its configuration (e.g. broadcast frames, transmit
	// power).
	// This field provides a place to store and control access to that
	// key.
	// This field is populated in responses to `GET
	// /v1beta1/beacons/3!beaconId`
	// from users with write access to the given beacon. That is to say: If
	// the
	// user is authorized to write the beacon's confidential data in the
	// service,
	// the service considers them authorized to configure the beacon.
	// Note
	// that this key grants nothing on the service, only on the beacon
	// itself.
	ProvisioningKey string `json:"provisioningKey,omitempty"`

	// Status: Current status of the beacon.
	// Required.
	//
	// Possible values:
	//   "STATUS_UNSPECIFIED" - Do not use this value.
	//   "ACTIVE" - The "normal" in-use state of a beacon.
	//   "DECOMMISSIONED" - Beacon should no longer be used for any purpose.
	// This is irreversible.
	//   "INACTIVE" - The beacon should not be visible to mobile devices.
	// This is reversible.
	Status string `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. "AdvertisedId") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// 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. "AdvertisedId") 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 *Beacon) MarshalJSON() ([]byte, error) {
	type NoMethod Beacon
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// BeaconAttachment: Project-specific data associated with a beacon.
type BeaconAttachment struct {
	// AttachmentName: Resource name of this attachment. Attachment names
	// have the
	// format:
	// <code>beacons/<var>beacon_id</var>/attachments/<var>attachment
	// _id</var></code>.
	// Leave this empty on creation.
	AttachmentName string `json:"attachmentName,omitempty"`

	// CreationTimeMs: The UTC time when this attachment was created, in
	// milliseconds since the
	// UNIX epoch.
	CreationTimeMs string `json:"creationTimeMs,omitempty"`

	// Data: An opaque data container for client-provided data. Must
	// be
	// [base64](http://tools.ietf.org/html/rfc4648#section-4) encoded in
	// HTTP
	// requests, and will be so encoded (with padding) in
	// responses.
	// Required.
	Data string `json:"data,omitempty"`

	// MaxDistanceMeters: The distance away from the beacon at which this
	// attachment should be
	// delivered to a mobile app.
	//
	// Setting this to a value greater than zero indicates that the app
	// should
	// behave as if the beacon is "seen" when the mobile device is less than
	// this
	// distance away from the beacon.
	//
	// Different attachments on the same beacon can have different max
	// distances.
	//
	// Note that even though this value is expressed with fractional
	// meter
	// precision, real-world behavior is likley to be much less precise than
	// one
	// meter, due to the nature of current Bluetooth radio
	// technology.
	//
	// Optional. When not set or zero, the attachment should be delivered at
	// the
	// beacon's outer limit of detection.
	//
	// Negative values are invalid and return an error.
	MaxDistanceMeters float64 `json:"maxDistanceMeters,omitempty"`

	// NamespacedType: Specifies what kind of attachment this is. Tells a
	// client how to
	// interpret the `data` field. Format is <var>namespace/type</var>.
	// Namespace
	// provides type separation between clients. Type describes the type
	// of
	// `data`, for use by the client when parsing the `data`
	// field.
	// Required.
	NamespacedType string `json:"namespacedType,omitempty"`

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

	// ForceSendFields is a list of field names (e.g. "AttachmentName") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// 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. "AttachmentName") 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 *BeaconAttachment) MarshalJSON() ([]byte, error) {
	type NoMethod BeaconAttachment
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

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

// BeaconInfo: A subset of beacon information served via the
// `beaconinfo.getforobserved`
// method, which you call when users of your app encounter your beacons.
type BeaconInfo struct {
	// AdvertisedId: The ID advertised by the beacon.
	AdvertisedId *AdvertisedId `json:"advertisedId,omitempty"`

	// Attachments: Attachments matching the type(s) requested.
	// May be empty if no attachment types were requested.
	Attachments []*AttachmentInfo `json:"attachments,omitempty"`

	// BeaconName: The name under which the beacon is registered.
	BeaconName string `json:"beaconName,omitempty"`

	// ForceSendFields is a list of field names (e.g. "AdvertisedId") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// 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. "AdvertisedId") 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 *BeaconInfo) MarshalJSON() ([]byte, error) {
	type NoMethod BeaconInfo
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Date: Represents a whole or partial calendar date, e.g. a birthday.
// The time of day
// and time zone are either specified elsewhere or are not significant.
// The date
// is relative to the Proleptic Gregorian Calendar. This can
// represent:
//
// * A full date, with non-zero year, month and day values
// * A month and day value, with a zero year, e.g. an anniversary
// * A year on its own, with zero month and day values
// * A year and month value, with a zero day, e.g. a credit card
// expiration date
//
// Related types are google.type.TimeOfDay and
// `google.protobuf.Timestamp`.
type Date struct {
	// Day: Day of month. Must be from 1 to 31 and valid for the year and
	// month, or 0
	// if specifying a year by itself or a year and month where the day is
	// not
	// significant.
	Day int64 `json:"day,omitempty"`

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

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

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

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

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

// DeleteAttachmentsResponse: Response for a request to delete
// attachments.
type DeleteAttachmentsResponse struct {
	// NumDeleted: The number of attachments that were deleted.
	NumDeleted int64 `json:"numDeleted,omitempty"`

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

	// ForceSendFields is a list of field names (e.g. "NumDeleted") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// 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. "NumDeleted") 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 *DeleteAttachmentsResponse) MarshalJSON() ([]byte, error) {
	type NoMethod DeleteAttachmentsResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Diagnostics: Diagnostics for a single beacon.
type Diagnostics struct {
	// Alerts: An unordered list of Alerts that the beacon has.
	//
	// Possible values:
	//   "ALERT_UNSPECIFIED" - Invalid value. Should never appear.
	//   "WRONG_LOCATION" - The beacon has been reported far from its
	// expected location (the beacon's
	// lat_lng field if populated, otherwise, if the beacon's place_id field
	// is
	// present, the center of that place). This may indicate that the beacon
	// has
	// been moved. This signal is not 100% accurate, but indicates that
	// further
	// investigation is worthwhile.
	//   "LOW_BATTERY" - The battery level for the beacon is low enough
	// that, given the beacon's
	// current use, its battery will run out with in the next 60 days.
	// This
	// indicates that the battery should be replaced soon.
	//   "LOW_ACTIVITY" - The beacon has been reported at a very low rate or
	// not at all. This may
	// indicate that the beacon is broken or just that no one has gone near
	// the
	// beacon in recent days. If this status appears unexpectedly, the
	// beacon
	// owner should investigate further.
	Alerts []string `json:"alerts,omitempty"`

	// BeaconName: Resource name of the beacon. For Eddystone-EID beacons,
	// this may
	// be the beacon's current EID, or the beacon's "stable" Eddystone-UID.
	BeaconName string `json:"beaconName,omitempty"`

	// EstimatedLowBatteryDate: The date when the battery is expected to be
	// low. If the value is missing
	// then there is no estimate for when the battery will be low.
	// This value is only an estimate, not an exact date.
	EstimatedLowBatteryDate *Date `json:"estimatedLowBatteryDate,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Alerts") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// 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. "Alerts") 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 *Diagnostics) MarshalJSON() ([]byte, error) {
	type NoMethod Diagnostics
	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:"-"`
}

// EphemeralIdRegistration: Write-only registration parameters for
// beacons using Eddystone-EID format.
// Two ways of securely registering an Eddystone-EID beacon with the
// service
// are supported:
//
// 1. Perform an ECDH key exchange via this API, including a previous
// call
//    to `GET /v1beta1/eidparams`. In this case the fields
//    `beacon_ecdh_public_key` and `service_ecdh_public_key` should be
//    populated and `beacon_identity_key` should not be populated. This
//    method ensures that only the two parties in the ECDH key exchange
// can
//    compute the identity key, which becomes a secret between them.
// 2. Derive or obtain the beacon's identity key via other secure means
//    (perhaps an ECDH key exchange between the beacon and a mobile
// device
//    or any other secure method), and then submit the resulting
// identity key
//    to the service. In this case `beacon_identity_key` field should
// be
//    populated, and neither of `beacon_ecdh_public_key` nor
//    `service_ecdh_public_key` fields should be. The security of this
// method
//    depends on how securely the parties involved (in particular the
//    bluetooth client) handle the identity key, and obviously on how
//    securely the identity key was generated.
//
// See [the
// Eddystone
// specification](https://github.com/google/eddystone/tree/mast
// er/eddystone-eid)
// at GitHub.
type EphemeralIdRegistration struct {
	// BeaconEcdhPublicKey: The beacon's public key used for the Elliptic
	// curve Diffie-Hellman
	// key exchange. When this field is populated,
	// `service_ecdh_public_key`
	// must also be populated, and `beacon_identity_key` must not be.
	BeaconEcdhPublicKey string `json:"beaconEcdhPublicKey,omitempty"`

	// BeaconIdentityKey: The private key of the beacon. If this field is
	// populated,
	// `beacon_ecdh_public_key` and `service_ecdh_public_key` must not
	// be
	// populated.
	BeaconIdentityKey string `json:"beaconIdentityKey,omitempty"`

	// InitialClockValue: The initial clock value of the beacon. The
	// beacon's clock must have
	// begun counting at this value immediately prior to transmitting
	// this
	// value to the resolving service. Significant delay in transmitting
	// this
	// value to the service risks registration or resolution failures. If
	// a
	// value is not provided, the default is zero.
	InitialClockValue uint64 `json:"initialClockValue,omitempty,string"`

	// InitialEid: An initial ephemeral ID calculated using the clock value
	// submitted as
	// `initial_clock_value`, and the secret key generated by
	// the
	// Diffie-Hellman key exchange using `service_ecdh_public_key`
	// and
	// `service_ecdh_public_key`. This initial EID value will be used by
	// the
	// service to confirm that the key exchange process was successful.
	InitialEid string `json:"initialEid,omitempty"`

	// RotationPeriodExponent: Indicates the nominal period between each
	// rotation of the beacon's
	// ephemeral ID. "Nominal" because the beacon should randomize
	// the
	// actual interval. See [the spec
	// at
	// github](https://github.com/google/eddystone/tree/master/eddystone-e
	// id)
	// for details. This value corresponds to a power-of-two scaler on
	// the
	// beacon's clock: when the scaler value is K, the beacon will
	// begin
	// broadcasting a new ephemeral ID on average every 2^K seconds.
	RotationPeriodExponent int64 `json:"rotationPeriodExponent,omitempty"`

	// ServiceEcdhPublicKey: The service's public key used for the Elliptic
	// curve Diffie-Hellman
	// key exchange. When this field is populated,
	// `beacon_ecdh_public_key`
	// must also be populated, and `beacon_identity_key` must not be.
	ServiceEcdhPublicKey string `json:"serviceEcdhPublicKey,omitempty"`

	// ForceSendFields is a list of field names (e.g. "BeaconEcdhPublicKey")
	// to unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// 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. "BeaconEcdhPublicKey") 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 *EphemeralIdRegistration) MarshalJSON() ([]byte, error) {
	type NoMethod EphemeralIdRegistration
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// EphemeralIdRegistrationParams: Information a client needs to
// provision and register beacons that
// broadcast Eddystone-EID format beacon IDs, using Elliptic
// curve
// Diffie-Hellman key exchange. See
// [the
// Eddystone
// specification](https://github.com/google/eddystone/tree/mast
// er/eddystone-eid)
// at GitHub.
type EphemeralIdRegistrationParams struct {
	// MaxRotationPeriodExponent: Indicates the maximum rotation period
	// supported by the
	// service.
	// See
	// EddystoneEidRegistration.rotation_period_exponent
	MaxRotationPeriodExponent int64 `json:"maxRotationPeriodExponent,omitempty"`

	// MinRotationPeriodExponent: Indicates the minimum rotation period
	// supported by the
	// service.
	// See
	// EddystoneEidRegistration.rotation_period_exponent
	MinRotationPeriodExponent int64 `json:"minRotationPeriodExponent,omitempty"`

	// ServiceEcdhPublicKey: The beacon service's public key for use by a
	// beacon to derive its
	// Identity Key using Elliptic Curve Diffie-Hellman key exchange.
	ServiceEcdhPublicKey string `json:"serviceEcdhPublicKey,omitempty"`

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

	// ForceSendFields is a list of field names (e.g.
	// "MaxRotationPeriodExponent") to unconditionally include in API
	// requests. By default, fields with empty values are omitted from API
	// requests. However, any non-pointer, non-interface field appearing in
	// ForceSendFields will be sent to the 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.
	// "MaxRotationPeriodExponent") 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 *EphemeralIdRegistrationParams) MarshalJSON() ([]byte, error) {
	type NoMethod EphemeralIdRegistrationParams
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GetInfoForObservedBeaconsRequest: Request for beacon and attachment
// information about beacons that
// a mobile client has encountered "in the wild".
type GetInfoForObservedBeaconsRequest struct {
	// NamespacedTypes: Specifies what kind of attachments to include in the
	// response.
	// When given, the response will include only attachments of the given
	// types.
	// When empty, no attachments will be returned. Must be in the
	// format
	// <var>namespace/type</var>. Accepts `*` to specify all types in
	// all namespaces owned by the client.
	// Optional.
	NamespacedTypes []string `json:"namespacedTypes,omitempty"`

	// Observations: The beacons that the client has encountered.
	// At least one must be given.
	Observations []*Observation `json:"observations,omitempty"`

	// ForceSendFields is a list of field names (e.g. "NamespacedTypes") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// 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. "NamespacedTypes") 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 *GetInfoForObservedBeaconsRequest) MarshalJSON() ([]byte, error) {
	type NoMethod GetInfoForObservedBeaconsRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GetInfoForObservedBeaconsResponse: Information about the requested
// beacons, optionally including attachment
// data.
type GetInfoForObservedBeaconsResponse struct {
	// Beacons: Public information about beacons.
	// May be empty if the request matched no beacons.
	Beacons []*BeaconInfo `json:"beacons,omitempty"`

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

	// ForceSendFields is a list of field names (e.g. "Beacons") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// 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. "Beacons") 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 *GetInfoForObservedBeaconsResponse) MarshalJSON() ([]byte, error) {
	type NoMethod GetInfoForObservedBeaconsResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// IndoorLevel: Indoor level, a human-readable string as returned by
// Google Maps APIs,
// useful to indicate which floor of a building a beacon is located on.
type IndoorLevel struct {
	// Name: The name of this level.
	Name string `json:"name,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 *IndoorLevel) MarshalJSON() ([]byte, error) {
	type NoMethod IndoorLevel
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// 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
}

// ListBeaconAttachmentsResponse: Response to `ListBeaconAttachments`
// that contains the requested attachments.
type ListBeaconAttachmentsResponse struct {
	// Attachments: The attachments that corresponded to the request params.
	Attachments []*BeaconAttachment `json:"attachments,omitempty"`

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

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

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

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

// ListBeaconsResponse: Response that contains list beacon results and
// pagination help.
type ListBeaconsResponse struct {
	// Beacons: The beacons that matched the search criteria.
	Beacons []*Beacon `json:"beacons,omitempty"`

	// NextPageToken: An opaque pagination token that the client may provide
	// in their next
	// request to retrieve the next page of results.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// TotalCount: Estimate of the total number of beacons matched by the
	// query. Higher
	// values may be less accurate.
	TotalCount int64 `json:"totalCount,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. "Beacons") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// 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. "Beacons") 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 *ListBeaconsResponse) MarshalJSON() ([]byte, error) {
	type NoMethod ListBeaconsResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ListDiagnosticsResponse: Response that contains the requested
// diagnostics.
type ListDiagnosticsResponse struct {
	// Diagnostics: The diagnostics matching the given request.
	Diagnostics []*Diagnostics `json:"diagnostics,omitempty"`

	// NextPageToken: Token that can be used for pagination. Returned only
	// if the
	// request matches more beacons than can be returned in this response.
	NextPageToken string `json:"nextPageToken,omitempty"`

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

	// ForceSendFields is a list of field names (e.g. "Diagnostics") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// 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. "Diagnostics") 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 *ListDiagnosticsResponse) MarshalJSON() ([]byte, error) {
	type NoMethod ListDiagnosticsResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ListNamespacesResponse: Response to ListNamespacesRequest that
// contains all the project's namespaces.
type ListNamespacesResponse struct {
	// Namespaces: The attachments that corresponded to the request params.
	Namespaces []*Namespace `json:"namespaces,omitempty"`

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

	// ForceSendFields is a list of field names (e.g. "Namespaces") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// 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. "Namespaces") 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 *ListNamespacesResponse) MarshalJSON() ([]byte, error) {
	type NoMethod ListNamespacesResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Namespace: An attachment namespace defines read and write access for
// all the attachments
// created under it. Each namespace is globally unique, and owned by
// one
// project which is the only project that can create attachments under
// it.
type Namespace struct {
	// NamespaceName: Resource name of this namespace. Namespaces names have
	// the format:
	// <code>namespaces/<var>namespace</var></code>.
	NamespaceName string `json:"namespaceName,omitempty"`

	// ServingVisibility: Specifies what clients may receive attachments
	// under this namespace
	// via `beaconinfo.getforobserved`.
	//
	// Possible values:
	//   "VISIBILITY_UNSPECIFIED" - Do not use this value.
	//   "UNLISTED" - Served only to the project that owns the namespace.
	//   "PUBLIC" - Any project can subscribe to attachments under the
	// namespace.
	ServingVisibility string `json:"servingVisibility,omitempty"`

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

	// ForceSendFields is a list of field names (e.g. "NamespaceName") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// 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. "NamespaceName") 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 *Namespace) MarshalJSON() ([]byte, error) {
	type NoMethod Namespace
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Observation: Represents one beacon observed once.
type Observation struct {
	// AdvertisedId: The ID advertised by the beacon the client has
	// encountered.
	//
	// If the submitted `advertised_id` type is Eddystone-EID, then the
	// client
	// must be authorized to resolve the given beacon. Otherwise no data
	// will be
	// returned for that beacon.
	// Required.
	AdvertisedId *AdvertisedId `json:"advertisedId,omitempty"`

	// Telemetry: The array of telemetry bytes received from the beacon. The
	// server is
	// responsible for parsing it. This field may frequently be empty,
	// as
	// with a beacon that transmits telemetry only occasionally.
	Telemetry string `json:"telemetry,omitempty"`

	// TimestampMs: Time when the beacon was observed.
	TimestampMs string `json:"timestampMs,omitempty"`

	// ForceSendFields is a list of field names (e.g. "AdvertisedId") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// 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. "AdvertisedId") 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 *Observation) MarshalJSON() ([]byte, error) {
	type NoMethod Observation
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// method id "proximitybeacon.beaconinfo.getforobserved":

type BeaconinfoGetforobservedCall struct {
	s                                *Service
	getinfoforobservedbeaconsrequest *GetInfoForObservedBeaconsRequest
	urlParams_                       gensupport.URLParams
	ctx_                             context.Context
	header_                          http.Header
}

// Getforobserved: Given one or more beacon observations, returns any
// beacon information
// and attachments accessible to your application. Authorize by using
// the
// [API
// key](https://developers.google.com/beacons/proximity/get-star
// ted#request_a_browser_api_key)
// for the application.
func (r *BeaconinfoService) Getforobserved(getinfoforobservedbeaconsrequest *GetInfoForObservedBeaconsRequest) *BeaconinfoGetforobservedCall {
	c := &BeaconinfoGetforobservedCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.getinfoforobservedbeaconsrequest = getinfoforobservedbeaconsrequest
	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 *BeaconinfoGetforobservedCall) Fields(s ...googleapi.Field) *BeaconinfoGetforobservedCall {
	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 *BeaconinfoGetforobservedCall) Context(ctx context.Context) *BeaconinfoGetforobservedCall {
	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 *BeaconinfoGetforobservedCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *BeaconinfoGetforobservedCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20200222")
	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.getinfoforobservedbeaconsrequest)
	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, "v1beta1/beaconinfo:getforobserved")
	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 "proximitybeacon.beaconinfo.getforobserved" call.
// Exactly one of *GetInfoForObservedBeaconsResponse or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *GetInfoForObservedBeaconsResponse.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 *BeaconinfoGetforobservedCall) Do(opts ...googleapi.CallOption) (*GetInfoForObservedBeaconsResponse, 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 := &GetInfoForObservedBeaconsResponse{
		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": "Given one or more beacon observations, returns any beacon information\nand attachments accessible to your application. Authorize by using the\n[API\nkey](https://developers.google.com/beacons/proximity/get-started#request_a_browser_api_key)\nfor the application.",
	//   "flatPath": "v1beta1/beaconinfo:getforobserved",
	//   "httpMethod": "POST",
	//   "id": "proximitybeacon.beaconinfo.getforobserved",
	//   "parameterOrder": [],
	//   "parameters": {},
	//   "path": "v1beta1/beaconinfo:getforobserved",
	//   "request": {
	//     "$ref": "GetInfoForObservedBeaconsRequest"
	//   },
	//   "response": {
	//     "$ref": "GetInfoForObservedBeaconsResponse"
	//   }
	// }

}

// method id "proximitybeacon.beacons.activate":

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

// Activate: Activates a beacon. A beacon that is active will return
// information
// and attachment data when queried via
// `beaconinfo.getforobserved`.
// Calling this method on an already active beacon will do nothing
// (but
// will return a successful response code).
//
// Authenticate using an [OAuth
// access
// token](https://developers.google.com/identity/protocols/OAuth2)
//  from a
// signed-in user with **Is owner** or **Can edit** permissions in the
// Google
// Developers Console project.
func (r *BeaconsService) Activate(beaconName string) *BeaconsActivateCall {
	c := &BeaconsActivateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.beaconName = beaconName
	return c
}

// ProjectId sets the optional parameter "projectId": The project id of
// the beacon to activate. If the project id is not
// specified then the project making the request is used. The project
// id
// must match the project that owns the beacon.
func (c *BeaconsActivateCall) ProjectId(projectId string) *BeaconsActivateCall {
	c.urlParams_.Set("projectId", projectId)
	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 *BeaconsActivateCall) Fields(s ...googleapi.Field) *BeaconsActivateCall {
	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 *BeaconsActivateCall) Context(ctx context.Context) *BeaconsActivateCall {
	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 *BeaconsActivateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

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

// Do executes the "proximitybeacon.beacons.activate" 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 *BeaconsActivateCall) 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": "Activates a beacon. A beacon that is active will return information\nand attachment data when queried via `beaconinfo.getforobserved`.\nCalling this method on an already active beacon will do nothing (but\nwill return a successful response code).\n\nAuthenticate using an [OAuth access\ntoken](https://developers.google.com/identity/protocols/OAuth2) from a\nsigned-in user with **Is owner** or **Can edit** permissions in the Google\nDevelopers Console project.",
	//   "flatPath": "v1beta1/beacons/{beaconsId}:activate",
	//   "httpMethod": "POST",
	//   "id": "proximitybeacon.beacons.activate",
	//   "parameterOrder": [
	//     "beaconName"
	//   ],
	//   "parameters": {
	//     "beaconName": {
	//       "description": "Beacon that should be activated. A beacon name has the format\n\"beacons/N!beaconId\" where the beaconId is the base16 ID broadcast by\nthe beacon and N is a code for the beacon's type. Possible values are\n`3` for Eddystone-UID, `4` for Eddystone-EID, `1` for iBeacon, or `5`\nfor AltBeacon. For Eddystone-EID beacons, you may use either the\ncurrent EID or the beacon's \"stable\" UID.\nRequired.",
	//       "location": "path",
	//       "pattern": "^beacons/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "projectId": {
	//       "description": "The project id of the beacon to activate. If the project id is not\nspecified then the project making the request is used. The project id\nmust match the project that owns the beacon.\nOptional.",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1beta1/{+beaconName}:activate",
	//   "response": {
	//     "$ref": "Empty"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/userlocation.beacon.registry"
	//   ]
	// }

}

// method id "proximitybeacon.beacons.deactivate":

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

// Deactivate: Deactivates a beacon. Once deactivated, the API will not
// return
// information nor attachment data for the beacon when queried
// via
// `beaconinfo.getforobserved`. Calling this method on an already
// inactive
// beacon will do nothing (but will return a successful response
// code).
//
// Authenticate using an [OAuth
// access
// token](https://developers.google.com/identity/protocols/OAuth2)
//  from a
// signed-in user with **Is owner** or **Can edit** permissions in the
// Google
// Developers Console project.
func (r *BeaconsService) Deactivate(beaconName string) *BeaconsDeactivateCall {
	c := &BeaconsDeactivateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.beaconName = beaconName
	return c
}

// ProjectId sets the optional parameter "projectId": The project id of
// the beacon to deactivate. If the project id is not
// specified then the project making the request is used. The project id
// must
// match the project that owns the beacon.
func (c *BeaconsDeactivateCall) ProjectId(projectId string) *BeaconsDeactivateCall {
	c.urlParams_.Set("projectId", projectId)
	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 *BeaconsDeactivateCall) Fields(s ...googleapi.Field) *BeaconsDeactivateCall {
	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 *BeaconsDeactivateCall) Context(ctx context.Context) *BeaconsDeactivateCall {
	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 *BeaconsDeactivateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

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

// Do executes the "proximitybeacon.beacons.deactivate" 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 *BeaconsDeactivateCall) 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": "Deactivates a beacon. Once deactivated, the API will not return\ninformation nor attachment data for the beacon when queried via\n`beaconinfo.getforobserved`. Calling this method on an already inactive\nbeacon will do nothing (but will return a successful response code).\n\nAuthenticate using an [OAuth access\ntoken](https://developers.google.com/identity/protocols/OAuth2) from a\nsigned-in user with **Is owner** or **Can edit** permissions in the Google\nDevelopers Console project.",
	//   "flatPath": "v1beta1/beacons/{beaconsId}:deactivate",
	//   "httpMethod": "POST",
	//   "id": "proximitybeacon.beacons.deactivate",
	//   "parameterOrder": [
	//     "beaconName"
	//   ],
	//   "parameters": {
	//     "beaconName": {
	//       "description": "Beacon that should be deactivated. A beacon name has the format\n\"beacons/N!beaconId\" where the beaconId is the base16 ID broadcast by\nthe beacon and N is a code for the beacon's type. Possible values are\n`3` for Eddystone-UID, `4` for Eddystone-EID, `1` for iBeacon, or `5`\nfor AltBeacon. For Eddystone-EID beacons, you may use either the\ncurrent EID or the beacon's \"stable\" UID.\nRequired.",
	//       "location": "path",
	//       "pattern": "^beacons/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "projectId": {
	//       "description": "The project id of the beacon to deactivate. If the project id is not\nspecified then the project making the request is used. The project id must\nmatch the project that owns the beacon.\nOptional.",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1beta1/{+beaconName}:deactivate",
	//   "response": {
	//     "$ref": "Empty"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/userlocation.beacon.registry"
	//   ]
	// }

}

// method id "proximitybeacon.beacons.decommission":

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

// Decommission: Decommissions the specified beacon in the service. This
// beacon will no
// longer be returned from `beaconinfo.getforobserved`. This operation
// is
// permanent -- you will not be able to re-register a beacon with this
// ID
// again.
//
// Authenticate using an [OAuth
// access
// token](https://developers.google.com/identity/protocols/OAuth2)
//  from a
// signed-in user with **Is owner** or **Can edit** permissions in the
// Google
// Developers Console project.
func (r *BeaconsService) Decommission(beaconName string) *BeaconsDecommissionCall {
	c := &BeaconsDecommissionCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.beaconName = beaconName
	return c
}

// ProjectId sets the optional parameter "projectId": The project id of
// the beacon to decommission. If the project id is not
// specified then the project making the request is used. The project
// id
// must match the project that owns the beacon.
func (c *BeaconsDecommissionCall) ProjectId(projectId string) *BeaconsDecommissionCall {
	c.urlParams_.Set("projectId", projectId)
	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 *BeaconsDecommissionCall) Fields(s ...googleapi.Field) *BeaconsDecommissionCall {
	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 *BeaconsDecommissionCall) Context(ctx context.Context) *BeaconsDecommissionCall {
	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 *BeaconsDecommissionCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

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

// Do executes the "proximitybeacon.beacons.decommission" 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 *BeaconsDecommissionCall) 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": "Decommissions the specified beacon in the service. This beacon will no\nlonger be returned from `beaconinfo.getforobserved`. This operation is\npermanent -- you will not be able to re-register a beacon with this ID\nagain.\n\nAuthenticate using an [OAuth access\ntoken](https://developers.google.com/identity/protocols/OAuth2) from a\nsigned-in user with **Is owner** or **Can edit** permissions in the Google\nDevelopers Console project.",
	//   "flatPath": "v1beta1/beacons/{beaconsId}:decommission",
	//   "httpMethod": "POST",
	//   "id": "proximitybeacon.beacons.decommission",
	//   "parameterOrder": [
	//     "beaconName"
	//   ],
	//   "parameters": {
	//     "beaconName": {
	//       "description": "Beacon that should be decommissioned. A beacon name has the format\n\"beacons/N!beaconId\" where the beaconId is the base16 ID broadcast by\nthe beacon and N is a code for the beacon's type. Possible values are\n`3` for Eddystone-UID, `4` for Eddystone-EID, `1` for iBeacon, or `5`\nfor AltBeacon. For Eddystone-EID beacons, you may use either the\ncurrent EID of the beacon's \"stable\" UID.\nRequired.",
	//       "location": "path",
	//       "pattern": "^beacons/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "projectId": {
	//       "description": "The project id of the beacon to decommission. If the project id is not\nspecified then the project making the request is used. The project id\nmust match the project that owns the beacon.\nOptional.",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1beta1/{+beaconName}:decommission",
	//   "response": {
	//     "$ref": "Empty"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/userlocation.beacon.registry"
	//   ]
	// }

}

// method id "proximitybeacon.beacons.delete":

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

// Delete: Deletes the specified beacon including all diagnostics data
// for the beacon
// as well as any attachments on the beacon (including those belonging
// to
// other projects). This operation cannot be undone.
//
// Authenticate using an [OAuth
// access
// token](https://developers.google.com/identity/protocols/OAuth2)
//  from a
// signed-in user with **Is owner** or **Can edit** permissions in the
// Google
// Developers Console project.
func (r *BeaconsService) Delete(beaconName string) *BeaconsDeleteCall {
	c := &BeaconsDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.beaconName = beaconName
	return c
}

// ProjectId sets the optional parameter "projectId": The project id of
// the beacon to delete. If not provided, the project
// that is making the request is used.
func (c *BeaconsDeleteCall) ProjectId(projectId string) *BeaconsDeleteCall {
	c.urlParams_.Set("projectId", projectId)
	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 *BeaconsDeleteCall) Fields(s ...googleapi.Field) *BeaconsDeleteCall {
	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 *BeaconsDeleteCall) Context(ctx context.Context) *BeaconsDeleteCall {
	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 *BeaconsDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

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

// Do executes the "proximitybeacon.beacons.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 *BeaconsDeleteCall) 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 the specified beacon including all diagnostics data for the beacon\nas well as any attachments on the beacon (including those belonging to\nother projects). This operation cannot be undone.\n\nAuthenticate using an [OAuth access\ntoken](https://developers.google.com/identity/protocols/OAuth2) from a\nsigned-in user with **Is owner** or **Can edit** permissions in the Google\nDevelopers Console project.",
	//   "flatPath": "v1beta1/beacons/{beaconsId}",
	//   "httpMethod": "DELETE",
	//   "id": "proximitybeacon.beacons.delete",
	//   "parameterOrder": [
	//     "beaconName"
	//   ],
	//   "parameters": {
	//     "beaconName": {
	//       "description": "Beacon that should be deleted. A beacon name has the format\n\"beacons/N!beaconId\" where the beaconId is the base16 ID broadcast by\nthe beacon and N is a code for the beacon's type. Possible values are\n`3` for Eddystone-UID, `4` for Eddystone-EID, `1` for iBeacon, or `5`\nfor AltBeacon. For Eddystone-EID beacons, you may use either the\ncurrent EID or the beacon's \"stable\" UID.\nRequired.",
	//       "location": "path",
	//       "pattern": "^beacons/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "projectId": {
	//       "description": "The project id of the beacon to delete. If not provided, the project\nthat is making the request is used.\nOptional.",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1beta1/{+beaconName}",
	//   "response": {
	//     "$ref": "Empty"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/userlocation.beacon.registry"
	//   ]
	// }

}

// method id "proximitybeacon.beacons.get":

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

// Get: Returns detailed information about the specified
// beacon.
//
// Authenticate using an [OAuth
// access
// token](https://developers.google.com/identity/protocols/OAuth2)
//  from a
// signed-in user with **viewer**, **Is owner** or **Can edit**
// permissions in
// the Google Developers Console project.
//
// Requests may supply an Eddystone-EID beacon name in the
// form:
// `beacons/4!beaconId` where the `beaconId` is the base16 ephemeral
// ID
// broadcast by the beacon. The returned `Beacon` object will contain
// the
// beacon's stable Eddystone-UID. Clients not authorized to resolve
// the
// beacon's ephemeral Eddystone-EID broadcast will receive an error.
func (r *BeaconsService) Get(beaconName string) *BeaconsGetCall {
	c := &BeaconsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.beaconName = beaconName
	return c
}

// ProjectId sets the optional parameter "projectId": The project id of
// the beacon to request. If the project id is not specified
// then the project making the request is used. The project id must
// match the
// project that owns the beacon.
func (c *BeaconsGetCall) ProjectId(projectId string) *BeaconsGetCall {
	c.urlParams_.Set("projectId", projectId)
	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 *BeaconsGetCall) Fields(s ...googleapi.Field) *BeaconsGetCall {
	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 *BeaconsGetCall) IfNoneMatch(entityTag string) *BeaconsGetCall {
	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 *BeaconsGetCall) Context(ctx context.Context) *BeaconsGetCall {
	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 *BeaconsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

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

// Do executes the "proximitybeacon.beacons.get" call.
// Exactly one of *Beacon or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Beacon.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 *BeaconsGetCall) Do(opts ...googleapi.CallOption) (*Beacon, 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 := &Beacon{
		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": "Returns detailed information about the specified beacon.\n\nAuthenticate using an [OAuth access\ntoken](https://developers.google.com/identity/protocols/OAuth2) from a\nsigned-in user with **viewer**, **Is owner** or **Can edit** permissions in\nthe Google Developers Console project.\n\nRequests may supply an Eddystone-EID beacon name in the form:\n`beacons/4!beaconId` where the `beaconId` is the base16 ephemeral ID\nbroadcast by the beacon. The returned `Beacon` object will contain the\nbeacon's stable Eddystone-UID. Clients not authorized to resolve the\nbeacon's ephemeral Eddystone-EID broadcast will receive an error.",
	//   "flatPath": "v1beta1/beacons/{beaconsId}",
	//   "httpMethod": "GET",
	//   "id": "proximitybeacon.beacons.get",
	//   "parameterOrder": [
	//     "beaconName"
	//   ],
	//   "parameters": {
	//     "beaconName": {
	//       "description": "Resource name of this beacon. A beacon name has the format\n\"beacons/N!beaconId\" where the beaconId is the base16 ID broadcast by\nthe beacon and N is a code for the beacon's type. Possible values are\n`3` for Eddystone-UID, `4` for Eddystone-EID, `1` for iBeacon, or `5`\nfor AltBeacon. For Eddystone-EID beacons, you may use either the\ncurrent EID or the beacon's \"stable\" UID.\nRequired.",
	//       "location": "path",
	//       "pattern": "^beacons/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "projectId": {
	//       "description": "The project id of the beacon to request. If the project id is not specified\nthen the project making the request is used. The project id must match the\nproject that owns the beacon.\nOptional.",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1beta1/{+beaconName}",
	//   "response": {
	//     "$ref": "Beacon"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/userlocation.beacon.registry"
	//   ]
	// }

}

// method id "proximitybeacon.beacons.list":

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

// List: Searches the beacon registry for beacons that match the given
// search
// criteria. Only those beacons that the client has permission to
// list
// will be returned.
//
// Authenticate using an [OAuth
// access
// token](https://developers.google.com/identity/protocols/OAuth2)
//  from a
// signed-in user with **viewer**, **Is owner** or **Can edit**
// permissions in
// the Google Developers Console project.
func (r *BeaconsService) List() *BeaconsListCall {
	c := &BeaconsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	return c
}

// PageSize sets the optional parameter "pageSize": The maximum number
// of records to return for this request, up to a
// server-defined upper limit.
func (c *BeaconsListCall) PageSize(pageSize int64) *BeaconsListCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": A pagination token
// obtained from a previous request to list beacons.
func (c *BeaconsListCall) PageToken(pageToken string) *BeaconsListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// ProjectId sets the optional parameter "projectId": The project id to
// list beacons under. If not present then the project
// credential that made the request is used as the project.
func (c *BeaconsListCall) ProjectId(projectId string) *BeaconsListCall {
	c.urlParams_.Set("projectId", projectId)
	return c
}

// Q sets the optional parameter "q": Filter query string that supports
// the following field filters:
//
// * **description:"<string>"**
//   For example: **description:"Room 3"**
//   Returns beacons whose description matches tokens in the string
// "Room 3"
//   (not necessarily that exact string).
//   The string must be double-quoted.
// * **status:`<enum>`**
//   For example: **status:active**
//   Returns beacons whose status matches the given value. Values must
// be
//   one of the Beacon.Status enum values (case insensitive). Accepts
//   multiple filters which will be combined with OR logic.
// * **stability:`<enum>`**
//   For example: **stability:mobile**
//   Returns beacons whose expected stability matches the given value.
//   Values must be one of the Beacon.Stability enum values (case
//   insensitive). Accepts multiple filters which will be combined with
//   OR logic.
// * **place\_id:"<string>"**
//   For example: **place\_id:"ChIJVSZzVR8FdkgRXGmmm6SslKw="**
//   Returns beacons explicitly registered at the given place, expressed
// as
//   a Place ID obtained from [Google Places API](/places/place-id).
// Does not
//   match places inside the given place. Does not consider the
// beacon's
//   actual location (which may be different from its registered
// place).
//   Accepts multiple filters that will be combined with OR logic. The
// place
//   ID must be double-quoted.
// * **registration\_time`[<|>|<=|>=]<integer>`**
//   For example: **registration\_time>=1433116800**
//   Returns beacons whose registration time matches the given filter.
//   Supports the operators: <, >, <=, and >=. Timestamp must be
// expressed as
//   an integer number of seconds since midnight January 1, 1970 UTC.
// Accepts
//   at most two filters that will be combined with AND logic, to
// support
//   "between" semantics. If more than two are supplied, the latter ones
// are
//   ignored.
// * **lat:`<double> lng:<double> radius:<integer>`**
//   For example: **lat:51.1232343 lng:-1.093852 radius:1000**
//   Returns beacons whose registered location is within the given
// circle.
//   When any of these fields are given, all are required. Latitude and
//   longitude must be decimal degrees between -90.0 and 90.0 and
// between
//   -180.0 and 180.0 respectively. Radius must be an integer number of
//   meters between 10 and 1,000,000 (1000 km).
// * **property:"<string>=<string>"**
//   For example: **property:"battery-type=CR2032"**
//   Returns beacons which have a property of the given name and value.
//   Supports multiple filters which will be combined with OR logic.
//   The entire name=value string must be double-quoted as one string.
// * **attachment\_type:"<string>"**
//   For example: **attachment_type:"my-namespace/my-type"**
//   Returns beacons having at least one attachment of the given
// namespaced
//   type. Supports "any within this namespace" via the partial
// wildcard
//   syntax: "my-namespace/*". Supports multiple filters which will be
//   combined with OR logic. The string must be double-quoted.
// * **indoor\_level:"<string>"**
//   For example: **indoor\_level:"1"**
//   Returns beacons which are located on the given indoor level.
// Accepts
//   multiple filters that will be combined with OR logic.
//
// Multiple filters on the same field are combined with OR logic
// (except
// registration_time which is combined with AND logic).
// Multiple filters on different fields are combined with AND
// logic.
// Filters should be separated by spaces.
//
// As with any HTTP query string parameter, the whole filter expression
// must
// be URL-encoded.
//
// Example REST
// request:
// `GET
// /v1beta1/beacons?q=status:active%20lat:51.123%20lng:-1.0
// 95%20radius:1000`
func (c *BeaconsListCall) Q(q string) *BeaconsListCall {
	c.urlParams_.Set("q", q)
	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 *BeaconsListCall) Fields(s ...googleapi.Field) *BeaconsListCall {
	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 *BeaconsListCall) IfNoneMatch(entityTag string) *BeaconsListCall {
	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 *BeaconsListCall) Context(ctx context.Context) *BeaconsListCall {
	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 *BeaconsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *BeaconsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20200222")
	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, "v1beta1/beacons")
	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 "proximitybeacon.beacons.list" call.
// Exactly one of *ListBeaconsResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *ListBeaconsResponse.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 *BeaconsListCall) Do(opts ...googleapi.CallOption) (*ListBeaconsResponse, 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 := &ListBeaconsResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Searches the beacon registry for beacons that match the given search\ncriteria. Only those beacons that the client has permission to list\nwill be returned.\n\nAuthenticate using an [OAuth access\ntoken](https://developers.google.com/identity/protocols/OAuth2) from a\nsigned-in user with **viewer**, **Is owner** or **Can edit** permissions in\nthe Google Developers Console project.",
	//   "flatPath": "v1beta1/beacons",
	//   "httpMethod": "GET",
	//   "id": "proximitybeacon.beacons.list",
	//   "parameterOrder": [],
	//   "parameters": {
	//     "pageSize": {
	//       "description": "The maximum number of records to return for this request, up to a\nserver-defined upper limit.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "A pagination token obtained from a previous request to list beacons.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "projectId": {
	//       "description": "The project id to list beacons under. If not present then the project\ncredential that made the request is used as the project.\nOptional.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "q": {
	//       "description": "Filter query string that supports the following field filters:\n\n* **description:`\"\u003cstring\u003e\"`**\n  For example: **description:\"Room 3\"**\n  Returns beacons whose description matches tokens in the string \"Room 3\"\n  (not necessarily that exact string).\n  The string must be double-quoted.\n* **status:`\u003cenum\u003e`**\n  For example: **status:active**\n  Returns beacons whose status matches the given value. Values must be\n  one of the Beacon.Status enum values (case insensitive). Accepts\n  multiple filters which will be combined with OR logic.\n* **stability:`\u003cenum\u003e`**\n  For example: **stability:mobile**\n  Returns beacons whose expected stability matches the given value.\n  Values must be one of the Beacon.Stability enum values (case\n  insensitive). Accepts multiple filters which will be combined with\n  OR logic.\n* **place\\_id:`\"\u003cstring\u003e\"`**\n  For example: **place\\_id:\"ChIJVSZzVR8FdkgRXGmmm6SslKw=\"**\n  Returns beacons explicitly registered at the given place, expressed as\n  a Place ID obtained from [Google Places API](/places/place-id). Does not\n  match places inside the given place. Does not consider the beacon's\n  actual location (which may be different from its registered place).\n  Accepts multiple filters that will be combined with OR logic. The place\n  ID must be double-quoted.\n* **registration\\_time`[\u003c|\u003e|\u003c=|\u003e=]\u003cinteger\u003e`**\n  For example: **registration\\_time\u003e=1433116800**\n  Returns beacons whose registration time matches the given filter.\n  Supports the operators: \u003c, \u003e, \u003c=, and \u003e=. Timestamp must be expressed as\n  an integer number of seconds since midnight January 1, 1970 UTC. Accepts\n  at most two filters that will be combined with AND logic, to support\n  \"between\" semantics. If more than two are supplied, the latter ones are\n  ignored.\n* **lat:`\u003cdouble\u003e lng:\u003cdouble\u003e radius:\u003cinteger\u003e`**\n  For example: **lat:51.1232343 lng:-1.093852 radius:1000**\n  Returns beacons whose registered location is within the given circle.\n  When any of these fields are given, all are required. Latitude and\n  longitude must be decimal degrees between -90.0 and 90.0 and between\n  -180.0 and 180.0 respectively. Radius must be an integer number of\n  meters between 10 and 1,000,000 (1000 km).\n* **property:`\"\u003cstring\u003e=\u003cstring\u003e\"`**\n  For example: **property:\"battery-type=CR2032\"**\n  Returns beacons which have a property of the given name and value.\n  Supports multiple filters which will be combined with OR logic.\n  The entire name=value string must be double-quoted as one string.\n* **attachment\\_type:`\"\u003cstring\u003e\"`**\n  For example: **attachment_type:\"my-namespace/my-type\"**\n  Returns beacons having at least one attachment of the given namespaced\n  type. Supports \"any within this namespace\" via the partial wildcard\n  syntax: \"my-namespace/*\". Supports multiple filters which will be\n  combined with OR logic. The string must be double-quoted.\n* **indoor\\_level:`\"\u003cstring\u003e\"`**\n  For example: **indoor\\_level:\"1\"**\n  Returns beacons which are located on the given indoor level. Accepts\n  multiple filters that will be combined with OR logic.\n\nMultiple filters on the same field are combined with OR logic (except\nregistration_time which is combined with AND logic).\nMultiple filters on different fields are combined with AND logic.\nFilters should be separated by spaces.\n\nAs with any HTTP query string parameter, the whole filter expression must\nbe URL-encoded.\n\nExample REST request:\n`GET\n/v1beta1/beacons?q=status:active%20lat:51.123%20lng:-1.095%20radius:1000`",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1beta1/beacons",
	//   "response": {
	//     "$ref": "ListBeaconsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/userlocation.beacon.registry"
	//   ]
	// }

}

// 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 *BeaconsListCall) Pages(ctx context.Context, f func(*ListBeaconsResponse) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "proximitybeacon.beacons.register":

type BeaconsRegisterCall struct {
	s          *Service
	beacon     *Beacon
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Register: Registers a previously unregistered beacon given its
// `advertisedId`.
// These IDs are unique within the system. An ID can be registered only
// once.
//
// Authenticate using an [OAuth
// access
// token](https://developers.google.com/identity/protocols/OAuth2)
//  from a
// signed-in user with **Is owner** or **Can edit** permissions in the
// Google
// Developers Console project.
func (r *BeaconsService) Register(beacon *Beacon) *BeaconsRegisterCall {
	c := &BeaconsRegisterCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.beacon = beacon
	return c
}

// ProjectId sets the optional parameter "projectId": The project id of
// the project the beacon will be registered to. If
// the project id is not specified then the project making the
// request
// is used.
func (c *BeaconsRegisterCall) ProjectId(projectId string) *BeaconsRegisterCall {
	c.urlParams_.Set("projectId", projectId)
	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 *BeaconsRegisterCall) Fields(s ...googleapi.Field) *BeaconsRegisterCall {
	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 *BeaconsRegisterCall) Context(ctx context.Context) *BeaconsRegisterCall {
	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 *BeaconsRegisterCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *BeaconsRegisterCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20200222")
	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.beacon)
	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, "v1beta1/beacons:register")
	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 "proximitybeacon.beacons.register" call.
// Exactly one of *Beacon or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Beacon.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 *BeaconsRegisterCall) Do(opts ...googleapi.CallOption) (*Beacon, 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 := &Beacon{
		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": "Registers a previously unregistered beacon given its `advertisedId`.\nThese IDs are unique within the system. An ID can be registered only once.\n\nAuthenticate using an [OAuth access\ntoken](https://developers.google.com/identity/protocols/OAuth2) from a\nsigned-in user with **Is owner** or **Can edit** permissions in the Google\nDevelopers Console project.",
	//   "flatPath": "v1beta1/beacons:register",
	//   "httpMethod": "POST",
	//   "id": "proximitybeacon.beacons.register",
	//   "parameterOrder": [],
	//   "parameters": {
	//     "projectId": {
	//       "description": "The project id of the project the beacon will be registered to. If\nthe project id is not specified then the project making the request\nis used.\nOptional.",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1beta1/beacons:register",
	//   "request": {
	//     "$ref": "Beacon"
	//   },
	//   "response": {
	//     "$ref": "Beacon"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/userlocation.beacon.registry"
	//   ]
	// }

}

// method id "proximitybeacon.beacons.update":

type BeaconsUpdateCall struct {
	s          *Service
	beaconName string
	beacon     *Beacon
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Update: Updates the information about the specified beacon. **Any
// field that you do
// not populate in the submitted beacon will be permanently erased**, so
// you
// should follow the "read, modify, write" pattern to avoid
// inadvertently
// destroying data.
//
// Changes to the beacon status via this method will be  silently
// ignored.
// To update beacon status, use the separate methods on this API
// for
// activation, deactivation, and decommissioning.
// Authenticate using an [OAuth
// access
// token](https://developers.google.com/identity/protocols/OAuth2)
//  from a
// signed-in user with **Is owner** or **Can edit** permissions in the
// Google
// Developers Console project.
func (r *BeaconsService) Update(beaconName string, beacon *Beacon) *BeaconsUpdateCall {
	c := &BeaconsUpdateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.beaconName = beaconName
	c.beacon = beacon
	return c
}

// ProjectId sets the optional parameter "projectId": The project id of
// the beacon to update. If the project id is not
// specified then the project making the request is used. The project
// id
// must match the project that owns the beacon.
func (c *BeaconsUpdateCall) ProjectId(projectId string) *BeaconsUpdateCall {
	c.urlParams_.Set("projectId", projectId)
	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 *BeaconsUpdateCall) Fields(s ...googleapi.Field) *BeaconsUpdateCall {
	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 *BeaconsUpdateCall) Context(ctx context.Context) *BeaconsUpdateCall {
	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 *BeaconsUpdateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

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

// Do executes the "proximitybeacon.beacons.update" call.
// Exactly one of *Beacon or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Beacon.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 *BeaconsUpdateCall) Do(opts ...googleapi.CallOption) (*Beacon, 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 := &Beacon{
		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 information about the specified beacon. **Any field that you do\nnot populate in the submitted beacon will be permanently erased**, so you\nshould follow the \"read, modify, write\" pattern to avoid inadvertently\ndestroying data.\n\nChanges to the beacon status via this method will be  silently ignored.\nTo update beacon status, use the separate methods on this API for\nactivation, deactivation, and decommissioning.\nAuthenticate using an [OAuth access\ntoken](https://developers.google.com/identity/protocols/OAuth2) from a\nsigned-in user with **Is owner** or **Can edit** permissions in the Google\nDevelopers Console project.",
	//   "flatPath": "v1beta1/beacons/{beaconsId}",
	//   "httpMethod": "PUT",
	//   "id": "proximitybeacon.beacons.update",
	//   "parameterOrder": [
	//     "beaconName"
	//   ],
	//   "parameters": {
	//     "beaconName": {
	//       "description": "Resource name of this beacon. A beacon name has the format\n\"beacons/N!beaconId\" where the beaconId is the base16 ID broadcast by\nthe beacon and N is a code for the beacon's type. Possible values are\n`3` for Eddystone, `1` for iBeacon, or `5` for AltBeacon.\n\nThis field must be left empty when registering. After reading a beacon,\nclients can use the name for future operations.",
	//       "location": "path",
	//       "pattern": "^beacons/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "projectId": {
	//       "description": "The project id of the beacon to update. If the project id is not\nspecified then the project making the request is used. The project id\nmust match the project that owns the beacon.\nOptional.",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1beta1/{+beaconName}",
	//   "request": {
	//     "$ref": "Beacon"
	//   },
	//   "response": {
	//     "$ref": "Beacon"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/userlocation.beacon.registry"
	//   ]
	// }

}

// method id "proximitybeacon.beacons.attachments.batchDelete":

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

// BatchDelete: Deletes multiple attachments on a given beacon. This
// operation is
// permanent and cannot be undone.
//
// You can optionally specify `namespacedType` to choose which
// attachments
// should be deleted. If you do not specify `namespacedType`,  all
// your
// attachments on the given beacon will be deleted. You also may
// explicitly
// specify `*/*` to delete all.
//
// Authenticate using an [OAuth
// access
// token](https://developers.google.com/identity/protocols/OAuth2)
//  from a
// signed-in user with **Is owner** or **Can edit** permissions in the
// Google
// Developers Console project.
func (r *BeaconsAttachmentsService) BatchDelete(beaconName string) *BeaconsAttachmentsBatchDeleteCall {
	c := &BeaconsAttachmentsBatchDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.beaconName = beaconName
	return c
}

// NamespacedType sets the optional parameter "namespacedType":
// Specifies the namespace and type of attachments to delete
// in
// `namespace/type` format. Accepts `*/*` to specify
// "all types in all namespaces".
func (c *BeaconsAttachmentsBatchDeleteCall) NamespacedType(namespacedType string) *BeaconsAttachmentsBatchDeleteCall {
	c.urlParams_.Set("namespacedType", namespacedType)
	return c
}

// ProjectId sets the optional parameter "projectId": The project id to
// delete beacon attachments under. This field can be
// used when "*" is specified to mean all attachment namespaces.
// Projects
// may have multiple attachments with multiple namespaces. If "*"
// is
// specified and the projectId string is empty, then the project
// making the request is used.
func (c *BeaconsAttachmentsBatchDeleteCall) ProjectId(projectId string) *BeaconsAttachmentsBatchDeleteCall {
	c.urlParams_.Set("projectId", projectId)
	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 *BeaconsAttachmentsBatchDeleteCall) Fields(s ...googleapi.Field) *BeaconsAttachmentsBatchDeleteCall {
	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 *BeaconsAttachmentsBatchDeleteCall) Context(ctx context.Context) *BeaconsAttachmentsBatchDeleteCall {
	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 *BeaconsAttachmentsBatchDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

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

// Do executes the "proximitybeacon.beacons.attachments.batchDelete" call.
// Exactly one of *DeleteAttachmentsResponse or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *DeleteAttachmentsResponse.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 *BeaconsAttachmentsBatchDeleteCall) Do(opts ...googleapi.CallOption) (*DeleteAttachmentsResponse, 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 := &DeleteAttachmentsResponse{
		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 multiple attachments on a given beacon. This operation is\npermanent and cannot be undone.\n\nYou can optionally specify `namespacedType` to choose which attachments\nshould be deleted. If you do not specify `namespacedType`,  all your\nattachments on the given beacon will be deleted. You also may explicitly\nspecify `*/*` to delete all.\n\nAuthenticate using an [OAuth access\ntoken](https://developers.google.com/identity/protocols/OAuth2) from a\nsigned-in user with **Is owner** or **Can edit** permissions in the Google\nDevelopers Console project.",
	//   "flatPath": "v1beta1/beacons/{beaconsId}/attachments:batchDelete",
	//   "httpMethod": "POST",
	//   "id": "proximitybeacon.beacons.attachments.batchDelete",
	//   "parameterOrder": [
	//     "beaconName"
	//   ],
	//   "parameters": {
	//     "beaconName": {
	//       "description": "The beacon whose attachments should be deleted. A beacon name has the\nformat \"beacons/N!beaconId\" where the beaconId is the base16 ID broadcast\nby the beacon and N is a code for the beacon's type. Possible values are\n`3` for Eddystone-UID, `4` for Eddystone-EID, `1` for iBeacon, or `5`\nfor AltBeacon. For Eddystone-EID beacons, you may use either the\ncurrent EID or the beacon's \"stable\" UID.\nRequired.",
	//       "location": "path",
	//       "pattern": "^beacons/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "namespacedType": {
	//       "description": "Specifies the namespace and type of attachments to delete in\n`namespace/type` format. Accepts `*/*` to specify\n\"all types in all namespaces\".\nOptional.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "projectId": {
	//       "description": "The project id to delete beacon attachments under. This field can be\nused when \"*\" is specified to mean all attachment namespaces. Projects\nmay have multiple attachments with multiple namespaces. If \"*\" is\nspecified and the projectId string is empty, then the project\nmaking the request is used.\nOptional.",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1beta1/{+beaconName}/attachments:batchDelete",
	//   "response": {
	//     "$ref": "DeleteAttachmentsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/userlocation.beacon.registry"
	//   ]
	// }

}

// method id "proximitybeacon.beacons.attachments.create":

type BeaconsAttachmentsCreateCall struct {
	s                *Service
	beaconName       string
	beaconattachment *BeaconAttachment
	urlParams_       gensupport.URLParams
	ctx_             context.Context
	header_          http.Header
}

// Create: Associates the given data with the specified beacon.
// Attachment data must
// contain two parts:
// <ul>
// <li>A namespaced type.</li>
// <li>The actual attachment data itself.</li>
// </ul>
// The namespaced type consists of two parts, the namespace and the
// type.
// The namespace must be one of the values returned by the
// `namespaces`
// endpoint, while the type can be a string of any characters except for
// the
// forward slash (`/`) up to 100 characters in length.
//
// Attachment data can be up to 1024 bytes long.
//
// Authenticate using an [OAuth
// access
// token](https://developers.google.com/identity/protocols/OAuth2)
//  from a
// signed-in user with **Is owner** or **Can edit** permissions in the
// Google
// Developers Console project.
func (r *BeaconsAttachmentsService) Create(beaconName string, beaconattachment *BeaconAttachment) *BeaconsAttachmentsCreateCall {
	c := &BeaconsAttachmentsCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.beaconName = beaconName
	c.beaconattachment = beaconattachment
	return c
}

// ProjectId sets the optional parameter "projectId": The project id of
// the project the attachment will belong to. If
// the project id is not specified then the project making the
// request
// is used.
func (c *BeaconsAttachmentsCreateCall) ProjectId(projectId string) *BeaconsAttachmentsCreateCall {
	c.urlParams_.Set("projectId", projectId)
	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 *BeaconsAttachmentsCreateCall) Fields(s ...googleapi.Field) *BeaconsAttachmentsCreateCall {
	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 *BeaconsAttachmentsCreateCall) Context(ctx context.Context) *BeaconsAttachmentsCreateCall {
	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 *BeaconsAttachmentsCreateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

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

// Do executes the "proximitybeacon.beacons.attachments.create" call.
// Exactly one of *BeaconAttachment or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *BeaconAttachment.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 *BeaconsAttachmentsCreateCall) Do(opts ...googleapi.CallOption) (*BeaconAttachment, 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 := &BeaconAttachment{
		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": "Associates the given data with the specified beacon. Attachment data must\ncontain two parts:\n\u003cul\u003e\n\u003cli\u003eA namespaced type.\u003c/li\u003e\n\u003cli\u003eThe actual attachment data itself.\u003c/li\u003e\n\u003c/ul\u003e\nThe namespaced type consists of two parts, the namespace and the type.\nThe namespace must be one of the values returned by the `namespaces`\nendpoint, while the type can be a string of any characters except for the\nforward slash (`/`) up to 100 characters in length.\n\nAttachment data can be up to 1024 bytes long.\n\nAuthenticate using an [OAuth access\ntoken](https://developers.google.com/identity/protocols/OAuth2) from a\nsigned-in user with **Is owner** or **Can edit** permissions in the Google\nDevelopers Console project.",
	//   "flatPath": "v1beta1/beacons/{beaconsId}/attachments",
	//   "httpMethod": "POST",
	//   "id": "proximitybeacon.beacons.attachments.create",
	//   "parameterOrder": [
	//     "beaconName"
	//   ],
	//   "parameters": {
	//     "beaconName": {
	//       "description": "Beacon on which the attachment should be created. A beacon name has the\nformat \"beacons/N!beaconId\" where the beaconId is the base16 ID broadcast\nby the beacon and N is a code for the beacon's type. Possible values are\n`3` for Eddystone-UID, `4` for Eddystone-EID, `1` for iBeacon, or `5`\nfor AltBeacon. For Eddystone-EID beacons, you may use either the\ncurrent EID or the beacon's \"stable\" UID.\nRequired.",
	//       "location": "path",
	//       "pattern": "^beacons/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "projectId": {
	//       "description": "The project id of the project the attachment will belong to. If\nthe project id is not specified then the project making the request\nis used.\nOptional.",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1beta1/{+beaconName}/attachments",
	//   "request": {
	//     "$ref": "BeaconAttachment"
	//   },
	//   "response": {
	//     "$ref": "BeaconAttachment"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/userlocation.beacon.registry"
	//   ]
	// }

}

// method id "proximitybeacon.beacons.attachments.delete":

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

// Delete: Deletes the specified attachment for the given beacon. Each
// attachment has
// a unique attachment name (`attachmentName`) which is returned when
// you
// fetch the attachment data via this API. You specify this with the
// delete
// request to control which attachment is removed. This operation cannot
// be
// undone.
//
// Authenticate using an [OAuth
// access
// token](https://developers.google.com/identity/protocols/OAuth2)
//  from a
// signed-in user with **Is owner** or **Can edit** permissions in the
// Google
// Developers Console project.
func (r *BeaconsAttachmentsService) Delete(attachmentName string) *BeaconsAttachmentsDeleteCall {
	c := &BeaconsAttachmentsDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.attachmentName = attachmentName
	return c
}

// ProjectId sets the optional parameter "projectId": The project id of
// the attachment to delete. If not provided, the project
// that is making the request is used.
func (c *BeaconsAttachmentsDeleteCall) ProjectId(projectId string) *BeaconsAttachmentsDeleteCall {
	c.urlParams_.Set("projectId", projectId)
	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 *BeaconsAttachmentsDeleteCall) Fields(s ...googleapi.Field) *BeaconsAttachmentsDeleteCall {
	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 *BeaconsAttachmentsDeleteCall) Context(ctx context.Context) *BeaconsAttachmentsDeleteCall {
	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 *BeaconsAttachmentsDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

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

// Do executes the "proximitybeacon.beacons.attachments.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 *BeaconsAttachmentsDeleteCall) 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 the specified attachment for the given beacon. Each attachment has\na unique attachment name (`attachmentName`) which is returned when you\nfetch the attachment data via this API. You specify this with the delete\nrequest to control which attachment is removed. This operation cannot be\nundone.\n\nAuthenticate using an [OAuth access\ntoken](https://developers.google.com/identity/protocols/OAuth2) from a\nsigned-in user with **Is owner** or **Can edit** permissions in the Google\nDevelopers Console project.",
	//   "flatPath": "v1beta1/beacons/{beaconsId}/attachments/{attachmentsId}",
	//   "httpMethod": "DELETE",
	//   "id": "proximitybeacon.beacons.attachments.delete",
	//   "parameterOrder": [
	//     "attachmentName"
	//   ],
	//   "parameters": {
	//     "attachmentName": {
	//       "description": "The attachment name (`attachmentName`) of\nthe attachment to remove. For example:\n`beacons/3!893737abc9/attachments/c5e937-af0-494-959-ec49d12738`. For\nEddystone-EID beacons, the beacon ID portion (`3!893737abc9`) may be the\nbeacon's current EID, or its \"stable\" Eddystone-UID.\nRequired.",
	//       "location": "path",
	//       "pattern": "^beacons/[^/]+/attachments/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "projectId": {
	//       "description": "The project id of the attachment to delete. If not provided, the project\nthat is making the request is used.\nOptional.",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1beta1/{+attachmentName}",
	//   "response": {
	//     "$ref": "Empty"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/userlocation.beacon.registry"
	//   ]
	// }

}

// method id "proximitybeacon.beacons.attachments.list":

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

// List: Returns the attachments for the specified beacon that match the
// specified
// namespaced-type pattern.
//
// To control which namespaced types are returned, you add
// the
// `namespacedType` query parameter to the request. You must either
// use
// `*/*`, to return all attachments, or the namespace must be one of
// the ones returned from the  `namespaces` endpoint.
//
// Authenticate using an [OAuth
// access
// token](https://developers.google.com/identity/protocols/OAuth2)
//  from a
// signed-in user with **viewer**, **Is owner** or **Can edit**
// permissions in
// the Google Developers Console project.
func (r *BeaconsAttachmentsService) List(beaconName string) *BeaconsAttachmentsListCall {
	c := &BeaconsAttachmentsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.beaconName = beaconName
	return c
}

// NamespacedType sets the optional parameter "namespacedType":
// Specifies the namespace and type of attachment to include in response
// in
// <var>namespace/type</var> format. Accepts `*/*` to specify
// "all types in all namespaces".
func (c *BeaconsAttachmentsListCall) NamespacedType(namespacedType string) *BeaconsAttachmentsListCall {
	c.urlParams_.Set("namespacedType", namespacedType)
	return c
}

// ProjectId sets the optional parameter "projectId": The project id to
// list beacon attachments under. This field can be
// used when "*" is specified to mean all attachment namespaces.
// Projects
// may have multiple attachments with multiple namespaces. If "*"
// is
// specified and the projectId string is empty, then the project
// making the request is used.
func (c *BeaconsAttachmentsListCall) ProjectId(projectId string) *BeaconsAttachmentsListCall {
	c.urlParams_.Set("projectId", projectId)
	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 *BeaconsAttachmentsListCall) Fields(s ...googleapi.Field) *BeaconsAttachmentsListCall {
	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 *BeaconsAttachmentsListCall) IfNoneMatch(entityTag string) *BeaconsAttachmentsListCall {
	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 *BeaconsAttachmentsListCall) Context(ctx context.Context) *BeaconsAttachmentsListCall {
	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 *BeaconsAttachmentsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

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

// Do executes the "proximitybeacon.beacons.attachments.list" call.
// Exactly one of *ListBeaconAttachmentsResponse or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *ListBeaconAttachmentsResponse.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 *BeaconsAttachmentsListCall) Do(opts ...googleapi.CallOption) (*ListBeaconAttachmentsResponse, 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 := &ListBeaconAttachmentsResponse{
		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": "Returns the attachments for the specified beacon that match the specified\nnamespaced-type pattern.\n\nTo control which namespaced types are returned, you add the\n`namespacedType` query parameter to the request. You must either use\n`*/*`, to return all attachments, or the namespace must be one of\nthe ones returned from the  `namespaces` endpoint.\n\nAuthenticate using an [OAuth access\ntoken](https://developers.google.com/identity/protocols/OAuth2) from a\nsigned-in user with **viewer**, **Is owner** or **Can edit** permissions in\nthe Google Developers Console project.",
	//   "flatPath": "v1beta1/beacons/{beaconsId}/attachments",
	//   "httpMethod": "GET",
	//   "id": "proximitybeacon.beacons.attachments.list",
	//   "parameterOrder": [
	//     "beaconName"
	//   ],
	//   "parameters": {
	//     "beaconName": {
	//       "description": "Beacon whose attachments should be fetched. A beacon name has the\nformat \"beacons/N!beaconId\" where the beaconId is the base16 ID broadcast\nby the beacon and N is a code for the beacon's type. Possible values are\n`3` for Eddystone-UID, `4` for Eddystone-EID, `1` for iBeacon, or `5`\nfor AltBeacon. For Eddystone-EID beacons, you may use either the\ncurrent EID or the beacon's \"stable\" UID.\nRequired.",
	//       "location": "path",
	//       "pattern": "^beacons/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "namespacedType": {
	//       "description": "Specifies the namespace and type of attachment to include in response in\n\u003cvar\u003enamespace/type\u003c/var\u003e format. Accepts `*/*` to specify\n\"all types in all namespaces\".",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "projectId": {
	//       "description": "The project id to list beacon attachments under. This field can be\nused when \"*\" is specified to mean all attachment namespaces. Projects\nmay have multiple attachments with multiple namespaces. If \"*\" is\nspecified and the projectId string is empty, then the project\nmaking the request is used.\nOptional.",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1beta1/{+beaconName}/attachments",
	//   "response": {
	//     "$ref": "ListBeaconAttachmentsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/userlocation.beacon.registry"
	//   ]
	// }

}

// method id "proximitybeacon.beacons.diagnostics.list":

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

// List: List the diagnostics for a single beacon. You can also list
// diagnostics for
// all the beacons owned by your Google Developers Console project by
// using
// the beacon name `beacons/-`.
//
// Authenticate using an [OAuth
// access
// token](https://developers.google.com/identity/protocols/OAuth2)
//  from a
// signed-in user with **viewer**, **Is owner** or **Can edit**
// permissions in
// the Google Developers Console project.
func (r *BeaconsDiagnosticsService) List(beaconName string) *BeaconsDiagnosticsListCall {
	c := &BeaconsDiagnosticsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.beaconName = beaconName
	return c
}

// AlertFilter sets the optional parameter "alertFilter": Requests only
// beacons that have the given alert. For example, to find
// beacons that have low batteries use `alert_filter=LOW_BATTERY`.
//
// Possible values:
//   "ALERT_UNSPECIFIED"
//   "WRONG_LOCATION"
//   "LOW_BATTERY"
//   "LOW_ACTIVITY"
func (c *BeaconsDiagnosticsListCall) AlertFilter(alertFilter string) *BeaconsDiagnosticsListCall {
	c.urlParams_.Set("alertFilter", alertFilter)
	return c
}

// PageSize sets the optional parameter "pageSize": Specifies the
// maximum number of results to return. Defaults to
// 10. Maximum 1000.
func (c *BeaconsDiagnosticsListCall) PageSize(pageSize int64) *BeaconsDiagnosticsListCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": Requests results
// that occur after the `page_token`, obtained from the
// response to a previous request.
func (c *BeaconsDiagnosticsListCall) PageToken(pageToken string) *BeaconsDiagnosticsListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// ProjectId sets the optional parameter "projectId": Requests only
// diagnostic records for the given project id. If not set,
// then the project making the request will be used for looking
// up
// diagnostic records.
func (c *BeaconsDiagnosticsListCall) ProjectId(projectId string) *BeaconsDiagnosticsListCall {
	c.urlParams_.Set("projectId", projectId)
	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 *BeaconsDiagnosticsListCall) Fields(s ...googleapi.Field) *BeaconsDiagnosticsListCall {
	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 *BeaconsDiagnosticsListCall) IfNoneMatch(entityTag string) *BeaconsDiagnosticsListCall {
	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 *BeaconsDiagnosticsListCall) Context(ctx context.Context) *BeaconsDiagnosticsListCall {
	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 *BeaconsDiagnosticsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

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

// Do executes the "proximitybeacon.beacons.diagnostics.list" call.
// Exactly one of *ListDiagnosticsResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *ListDiagnosticsResponse.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 *BeaconsDiagnosticsListCall) Do(opts ...googleapi.CallOption) (*ListDiagnosticsResponse, 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 := &ListDiagnosticsResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "List the diagnostics for a single beacon. You can also list diagnostics for\nall the beacons owned by your Google Developers Console project by using\nthe beacon name `beacons/-`.\n\nAuthenticate using an [OAuth access\ntoken](https://developers.google.com/identity/protocols/OAuth2) from a\nsigned-in user with **viewer**, **Is owner** or **Can edit** permissions in\nthe Google Developers Console project.",
	//   "flatPath": "v1beta1/beacons/{beaconsId}/diagnostics",
	//   "httpMethod": "GET",
	//   "id": "proximitybeacon.beacons.diagnostics.list",
	//   "parameterOrder": [
	//     "beaconName"
	//   ],
	//   "parameters": {
	//     "alertFilter": {
	//       "description": "Requests only beacons that have the given alert. For example, to find\nbeacons that have low batteries use `alert_filter=LOW_BATTERY`.",
	//       "enum": [
	//         "ALERT_UNSPECIFIED",
	//         "WRONG_LOCATION",
	//         "LOW_BATTERY",
	//         "LOW_ACTIVITY"
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "beaconName": {
	//       "description": "Beacon that the diagnostics are for.",
	//       "location": "path",
	//       "pattern": "^beacons/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "pageSize": {
	//       "description": "Specifies the maximum number of results to return. Defaults to\n10. Maximum 1000. Optional.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "Requests results that occur after the `page_token`, obtained from the\nresponse to a previous request. Optional.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "projectId": {
	//       "description": "Requests only diagnostic records for the given project id. If not set,\nthen the project making the request will be used for looking up\ndiagnostic records. Optional.",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1beta1/{+beaconName}/diagnostics",
	//   "response": {
	//     "$ref": "ListDiagnosticsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/userlocation.beacon.registry"
	//   ]
	// }

}

// 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 *BeaconsDiagnosticsListCall) Pages(ctx context.Context, f func(*ListDiagnosticsResponse) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "proximitybeacon.namespaces.list":

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

// List: Lists all attachment namespaces owned by your Google Developers
// Console
// project. Attachment data associated with a beacon must include
// a
// namespaced type, and the namespace must be owned by your
// project.
//
// Authenticate using an [OAuth
// access
// token](https://developers.google.com/identity/protocols/OAuth2)
//  from a
// signed-in user with **viewer**, **Is owner** or **Can edit**
// permissions in
// the Google Developers Console project.
func (r *NamespacesService) List() *NamespacesListCall {
	c := &NamespacesListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	return c
}

// ProjectId sets the optional parameter "projectId": The project id to
// list namespaces under.
func (c *NamespacesListCall) ProjectId(projectId string) *NamespacesListCall {
	c.urlParams_.Set("projectId", projectId)
	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 *NamespacesListCall) Fields(s ...googleapi.Field) *NamespacesListCall {
	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 *NamespacesListCall) IfNoneMatch(entityTag string) *NamespacesListCall {
	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 *NamespacesListCall) Context(ctx context.Context) *NamespacesListCall {
	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 *NamespacesListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *NamespacesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20200222")
	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, "v1beta1/namespaces")
	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 "proximitybeacon.namespaces.list" call.
// Exactly one of *ListNamespacesResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *ListNamespacesResponse.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 *NamespacesListCall) Do(opts ...googleapi.CallOption) (*ListNamespacesResponse, 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 := &ListNamespacesResponse{
		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 attachment namespaces owned by your Google Developers Console\nproject. Attachment data associated with a beacon must include a\nnamespaced type, and the namespace must be owned by your project.\n\nAuthenticate using an [OAuth access\ntoken](https://developers.google.com/identity/protocols/OAuth2) from a\nsigned-in user with **viewer**, **Is owner** or **Can edit** permissions in\nthe Google Developers Console project.",
	//   "flatPath": "v1beta1/namespaces",
	//   "httpMethod": "GET",
	//   "id": "proximitybeacon.namespaces.list",
	//   "parameterOrder": [],
	//   "parameters": {
	//     "projectId": {
	//       "description": "The project id to list namespaces under.\nOptional.",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1beta1/namespaces",
	//   "response": {
	//     "$ref": "ListNamespacesResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/userlocation.beacon.registry"
	//   ]
	// }

}

// method id "proximitybeacon.namespaces.update":

type NamespacesUpdateCall struct {
	s             *Service
	namespaceName string
	namespace     *Namespace
	urlParams_    gensupport.URLParams
	ctx_          context.Context
	header_       http.Header
}

// Update: Updates the information about the specified namespace. Only
// the namespace
// visibility can be updated.
func (r *NamespacesService) Update(namespaceName string, namespace *Namespace) *NamespacesUpdateCall {
	c := &NamespacesUpdateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.namespaceName = namespaceName
	c.namespace = namespace
	return c
}

// ProjectId sets the optional parameter "projectId": The project id of
// the namespace to update. If the project id is not
// specified then the project making the request is used. The project
// id
// must match the project that owns the beacon.
func (c *NamespacesUpdateCall) ProjectId(projectId string) *NamespacesUpdateCall {
	c.urlParams_.Set("projectId", projectId)
	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 *NamespacesUpdateCall) Fields(s ...googleapi.Field) *NamespacesUpdateCall {
	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 *NamespacesUpdateCall) Context(ctx context.Context) *NamespacesUpdateCall {
	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 *NamespacesUpdateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

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

// Do executes the "proximitybeacon.namespaces.update" call.
// Exactly one of *Namespace or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Namespace.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 *NamespacesUpdateCall) Do(opts ...googleapi.CallOption) (*Namespace, 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 := &Namespace{
		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 information about the specified namespace. Only the namespace\nvisibility can be updated.",
	//   "flatPath": "v1beta1/namespaces/{namespacesId}",
	//   "httpMethod": "PUT",
	//   "id": "proximitybeacon.namespaces.update",
	//   "parameterOrder": [
	//     "namespaceName"
	//   ],
	//   "parameters": {
	//     "namespaceName": {
	//       "description": "Resource name of this namespace. Namespaces names have the format:\n\u003ccode\u003enamespaces/\u003cvar\u003enamespace\u003c/var\u003e\u003c/code\u003e.",
	//       "location": "path",
	//       "pattern": "^namespaces/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "projectId": {
	//       "description": "The project id of the namespace to update. If the project id is not\nspecified then the project making the request is used. The project id\nmust match the project that owns the beacon.\nOptional.",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1beta1/{+namespaceName}",
	//   "request": {
	//     "$ref": "Namespace"
	//   },
	//   "response": {
	//     "$ref": "Namespace"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/userlocation.beacon.registry"
	//   ]
	// }

}

// method id "proximitybeacon.getEidparams":

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

// GetEidparams: Gets the Proximity Beacon API's current public key and
// associated
// parameters used to initiate the Diffie-Hellman key exchange required
// to
// register a beacon that broadcasts the Eddystone-EID format. This
// key
// changes periodically; clients may cache it and re-use the same public
// key
// to provision and register multiple beacons. However, clients should
// be
// prepared to refresh this key when they encounter an error registering
// an
// Eddystone-EID beacon.
func (r *V1beta1Service) GetEidparams() *V1beta1GetEidparamsCall {
	c := &V1beta1GetEidparamsCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	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 *V1beta1GetEidparamsCall) Fields(s ...googleapi.Field) *V1beta1GetEidparamsCall {
	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 *V1beta1GetEidparamsCall) IfNoneMatch(entityTag string) *V1beta1GetEidparamsCall {
	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 *V1beta1GetEidparamsCall) Context(ctx context.Context) *V1beta1GetEidparamsCall {
	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 *V1beta1GetEidparamsCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *V1beta1GetEidparamsCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20200222")
	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, "v1beta1/eidparams")
	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 "proximitybeacon.getEidparams" call.
// Exactly one of *EphemeralIdRegistrationParams or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *EphemeralIdRegistrationParams.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 *V1beta1GetEidparamsCall) Do(opts ...googleapi.CallOption) (*EphemeralIdRegistrationParams, 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 := &EphemeralIdRegistrationParams{
		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 Proximity Beacon API's current public key and associated\nparameters used to initiate the Diffie-Hellman key exchange required to\nregister a beacon that broadcasts the Eddystone-EID format. This key\nchanges periodically; clients may cache it and re-use the same public key\nto provision and register multiple beacons. However, clients should be\nprepared to refresh this key when they encounter an error registering an\nEddystone-EID beacon.",
	//   "flatPath": "v1beta1/eidparams",
	//   "httpMethod": "GET",
	//   "id": "proximitybeacon.getEidparams",
	//   "parameterOrder": [],
	//   "parameters": {},
	//   "path": "v1beta1/eidparams",
	//   "response": {
	//     "$ref": "EphemeralIdRegistrationParams"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/userlocation.beacon.registry"
	//   ]
	// }

}
