// 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 firebasedynamiclinks provides access to the Firebase Dynamic Links API.
//
// For product documentation, see: https://firebase.google.com/docs/dynamic-links/
//
// Creating a client
//
// Usage example:
//
//   import "google.golang.org/api/firebasedynamiclinks/v1"
//   ...
//   ctx := context.Background()
//   firebasedynamiclinksService, err := firebasedynamiclinks.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:
//
//   firebasedynamiclinksService, err := firebasedynamiclinks.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, ...)
//   firebasedynamiclinksService, err := firebasedynamiclinks.NewService(ctx, option.WithTokenSource(config.TokenSource(ctx, token)))
//
// See https://godoc.org/google.golang.org/api/option/ for details on options.
package firebasedynamiclinks // import "google.golang.org/api/firebasedynamiclinks/v1"

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

	googleapi "google.golang.org/api/googleapi"
	gensupport "google.golang.org/api/internal/gensupport"
	option "google.golang.org/api/option"
	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 = "firebasedynamiclinks:v1"
const apiName = "firebasedynamiclinks"
const apiVersion = "v1"
const basePath = "https://firebasedynamiclinks.googleapis.com/"

// OAuth2 scopes used by this API.
const (
	// View and administer all your Firebase data and settings
	FirebaseScope = "https://www.googleapis.com/auth/firebase"
)

// NewService creates a new Service.
func NewService(ctx context.Context, opts ...option.ClientOption) (*Service, error) {
	scopesOption := option.WithScopes(
		"https://www.googleapis.com/auth/firebase",
	)
	// 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.ManagedShortLinks = NewManagedShortLinksService(s)
	s.ShortLinks = NewShortLinksService(s)
	s.V1 = NewV1Service(s)
	return s, nil
}

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

	ManagedShortLinks *ManagedShortLinksService

	ShortLinks *ShortLinksService

	V1 *V1Service
}

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

func NewManagedShortLinksService(s *Service) *ManagedShortLinksService {
	rs := &ManagedShortLinksService{s: s}
	return rs
}

type ManagedShortLinksService struct {
	s *Service
}

func NewShortLinksService(s *Service) *ShortLinksService {
	rs := &ShortLinksService{s: s}
	return rs
}

type ShortLinksService struct {
	s *Service
}

func NewV1Service(s *Service) *V1Service {
	rs := &V1Service{s: s}
	return rs
}

type V1Service struct {
	s *Service
}

// AnalyticsInfo: Tracking parameters supported by Dynamic Link.
type AnalyticsInfo struct {
	// GooglePlayAnalytics: Google Play Campaign Measurements.
	GooglePlayAnalytics *GooglePlayAnalytics `json:"googlePlayAnalytics,omitempty"`

	// ItunesConnectAnalytics: iTunes Connect App Analytics.
	ItunesConnectAnalytics *ITunesConnectAnalytics `json:"itunesConnectAnalytics,omitempty"`

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

// AndroidInfo: Android related attributes to the Dynamic Link.
type AndroidInfo struct {
	// AndroidFallbackLink: Link to open on Android if the app is not
	// installed.
	AndroidFallbackLink string `json:"androidFallbackLink,omitempty"`

	// AndroidLink: If specified, this overrides the ‘link’ parameter on
	// Android.
	AndroidLink string `json:"androidLink,omitempty"`

	// AndroidMinPackageVersionCode: Minimum version code for the Android
	// app. If the installed app’s version
	// code is lower, then the user is taken to the Play Store.
	AndroidMinPackageVersionCode string `json:"androidMinPackageVersionCode,omitempty"`

	// AndroidPackageName: Android package name of the app.
	AndroidPackageName string `json:"androidPackageName,omitempty"`

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

// CreateManagedShortLinkRequest: Request to create a managed Short
// Dynamic Link.
type CreateManagedShortLinkRequest struct {
	// DynamicLinkInfo: Information about the Dynamic Link to be
	// shortened.
	// [Learn
	// more](https://firebase.google.com/docs/reference/dyn
	// amic-links/link-shortener).
	DynamicLinkInfo *DynamicLinkInfo `json:"dynamicLinkInfo,omitempty"`

	// LongDynamicLink: Full long Dynamic Link URL with desired query
	// parameters specified.
	// For
	// example,
	// "https://sample.app.goo.gl/?link=http://www.google.com&apn=co
	// m.sample",
	// [Learn
	// more](https://firebase.google.com/docs/reference/dyn
	// amic-links/link-shortener).
	LongDynamicLink string `json:"longDynamicLink,omitempty"`

	// Name: Link name to associate with the link. It's used for marketer to
	// identify
	// manually-created links in the Firebase
	// console
	// (https://console.firebase.google.com/).
	// Links must be named to be tracked.
	Name string `json:"name,omitempty"`

	// SdkVersion: Google SDK version. Version takes the form
	// "$major.$minor.$patch"
	SdkVersion string `json:"sdkVersion,omitempty"`

	// Suffix: Short Dynamic Link suffix. Optional.
	Suffix *Suffix `json:"suffix,omitempty"`

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

// CreateManagedShortLinkResponse: Response to create a short Dynamic
// Link.
type CreateManagedShortLinkResponse struct {
	// ManagedShortLink: Short Dynamic Link value. e.g.
	// https://abcd.app.goo.gl/wxyz
	ManagedShortLink *ManagedShortLink `json:"managedShortLink,omitempty"`

	// PreviewLink: Preview link to show the link flow chart. (debug info.)
	PreviewLink string `json:"previewLink,omitempty"`

	// Warning: Information about potential warnings on link creation.
	Warning []*DynamicLinkWarning `json:"warning,omitempty"`

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

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

// CreateShortDynamicLinkRequest: Request to create a short Dynamic
// Link.
type CreateShortDynamicLinkRequest struct {
	// DynamicLinkInfo: Information about the Dynamic Link to be
	// shortened.
	// [Learn
	// more](https://firebase.google.com/docs/reference/dyn
	// amic-links/link-shortener).
	DynamicLinkInfo *DynamicLinkInfo `json:"dynamicLinkInfo,omitempty"`

	// LongDynamicLink: Full long Dynamic Link URL with desired query
	// parameters specified.
	// For
	// example,
	// "https://sample.app.goo.gl/?link=http://www.google.com&apn=co
	// m.sample",
	// [Learn
	// more](https://firebase.google.com/docs/reference/dyn
	// amic-links/link-shortener).
	LongDynamicLink string `json:"longDynamicLink,omitempty"`

	// SdkVersion: Google SDK version. Version takes the form
	// "$major.$minor.$patch"
	SdkVersion string `json:"sdkVersion,omitempty"`

	// Suffix: Short Dynamic Link suffix. Optional.
	Suffix *Suffix `json:"suffix,omitempty"`

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

// CreateShortDynamicLinkResponse: Response to create a short Dynamic
// Link.
type CreateShortDynamicLinkResponse struct {
	// PreviewLink: Preview link to show the link flow chart. (debug info.)
	PreviewLink string `json:"previewLink,omitempty"`

	// ShortLink: Short Dynamic Link value. e.g.
	// https://abcd.app.goo.gl/wxyz
	ShortLink string `json:"shortLink,omitempty"`

	// Warning: Information about potential warnings on link creation.
	Warning []*DynamicLinkWarning `json:"warning,omitempty"`

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

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

// DesktopInfo: Desktop related attributes to the Dynamic Link.
type DesktopInfo struct {
	// DesktopFallbackLink: Link to open on desktop.
	DesktopFallbackLink string `json:"desktopFallbackLink,omitempty"`

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

// DeviceInfo: Signals associated with the device making the request.
type DeviceInfo struct {
	// DeviceModelName: Device model name.
	DeviceModelName string `json:"deviceModelName,omitempty"`

	// LanguageCode: Device language code setting.
	LanguageCode string `json:"languageCode,omitempty"`

	// LanguageCodeFromWebview: Device language code setting obtained by
	// executing JavaScript code in
	// WebView.
	LanguageCodeFromWebview string `json:"languageCodeFromWebview,omitempty"`

	// LanguageCodeRaw: Device language code raw setting.
	// iOS does returns language code in different format than iOS
	// WebView.
	// For example WebView returns en_US, but iOS returns en-US.
	// Field below will return raw value returned by iOS.
	LanguageCodeRaw string `json:"languageCodeRaw,omitempty"`

	// ScreenResolutionHeight: Device display resolution height.
	ScreenResolutionHeight int64 `json:"screenResolutionHeight,omitempty,string"`

	// ScreenResolutionWidth: Device display resolution width.
	ScreenResolutionWidth int64 `json:"screenResolutionWidth,omitempty,string"`

	// Timezone: Device timezone setting.
	Timezone string `json:"timezone,omitempty"`

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

// DynamicLinkEventStat: Dynamic Link event stat.
type DynamicLinkEventStat struct {
	// Count: The number of times this event occurred.
	Count int64 `json:"count,omitempty,string"`

	// Event: Link event.
	//
	// Possible values:
	//   "DYNAMIC_LINK_EVENT_UNSPECIFIED" - Unspecified type.
	//   "CLICK" - Indicates that an FDL is clicked by users.
	//   "REDIRECT" - Indicates that an FDL redirects users to fallback
	// link.
	//   "APP_INSTALL" - Indicates that an FDL triggers an app install from
	// Play store, currently
	// it's impossible to get stats from App store.
	//   "APP_FIRST_OPEN" - Indicates that the app is opened for the first
	// time after an install
	// triggered by FDLs
	//   "APP_RE_OPEN" - Indicates that the app is opened via an FDL for
	// non-first time.
	Event string `json:"event,omitempty"`

	// Platform: Requested platform.
	//
	// Possible values:
	//   "DYNAMIC_LINK_PLATFORM_UNSPECIFIED" - Unspecified platform.
	//   "ANDROID" - Represents Android platform.
	// All apps and browsers on Android are classfied in this category.
	//   "IOS" - Represents iOS platform.
	// All apps and browsers on iOS are classfied in this category.
	//   "DESKTOP" - Represents desktop.
	//   "OTHER" - Platforms are not categorized as Android/iOS/Destop fall
	// into here.
	Platform string `json:"platform,omitempty"`

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

// DynamicLinkInfo: Information about a Dynamic Link.
type DynamicLinkInfo struct {
	// AnalyticsInfo: Parameters used for tracking. See all tracking
	// parameters in
	// the
	// [documentation](https://firebase.google.com/docs/dynamic-links/cre
	// ate-manually).
	AnalyticsInfo *AnalyticsInfo `json:"analyticsInfo,omitempty"`

	// AndroidInfo: Android related information. See Android related
	// parameters in
	// the
	// [documentation](https://firebase.google.com/docs/dynamic-links/cre
	// ate-manually).
	AndroidInfo *AndroidInfo `json:"androidInfo,omitempty"`

	// DesktopInfo: Desktop related information. See desktop related
	// parameters in
	// the
	// [documentation](https://firebase.google.com/docs/dynamic-links/cre
	// ate-manually).
	DesktopInfo *DesktopInfo `json:"desktopInfo,omitempty"`

	// DomainUriPrefix: E.g. https://maps.app.goo.gl,
	// https://maps.page.link, https://g.co/maps
	// More examples can be found in description of getNormalizedUriPrefix
	// in
	// j/c/g/firebase/dynamiclinks/uri/DdlDomain.java
	//
	// Will fallback to dynamic_link_domain is this field is missing
	DomainUriPrefix string `json:"domainUriPrefix,omitempty"`

	// DynamicLinkDomain: Dynamic Links domain that the project owns, e.g.
	// abcd.app.goo.gl
	// [Learn
	// more](https://firebase.google.com/docs/dynamic-
	// links/android/receive) on
	// how to set up Dynamic Link domain associated with your Firebase
	// project.
	//
	// Required if missing domain_uri_prefix.
	DynamicLinkDomain string `json:"dynamicLinkDomain,omitempty"`

	// IosInfo: iOS related information. See iOS related parameters in
	// the
	// [documentation](https://firebase.google.com/docs/dynamic-links/cre
	// ate-manually).
	IosInfo *IosInfo `json:"iosInfo,omitempty"`

	// Link: The link your app will open, You can specify any URL your app
	// can handle.
	// This link must be a well-formatted URL, be properly URL-encoded, and
	// use
	// the HTTP or HTTPS scheme. See 'link' parameters in
	// the
	// [documentation](https://firebase.google.com/docs/dynamic-links/cre
	// ate-manually).
	//
	// Required.
	Link string `json:"link,omitempty"`

	// NavigationInfo: Information of navigation behavior of a Firebase
	// Dynamic Links.
	NavigationInfo *NavigationInfo `json:"navigationInfo,omitempty"`

	// SocialMetaTagInfo: Parameters for social meta tag params.
	// Used to set meta tag data for link previews on social sites.
	SocialMetaTagInfo *SocialMetaTagInfo `json:"socialMetaTagInfo,omitempty"`

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

// DynamicLinkStats: Analytics stats of a Dynamic Link for a given
// timeframe.
type DynamicLinkStats struct {
	// LinkEventStats: Dynamic Link event stats.
	LinkEventStats []*DynamicLinkEventStat `json:"linkEventStats,omitempty"`

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

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

// DynamicLinkWarning: Dynamic Links warning messages.
type DynamicLinkWarning struct {
	// WarningCode: The warning code.
	//
	// Possible values:
	//   "CODE_UNSPECIFIED" - Unknown code.
	//   "NOT_IN_PROJECT_ANDROID_PACKAGE_NAME" - The Android package does
	// not match any in developer's DevConsole project.
	//   "NOT_INTEGER_ANDROID_PACKAGE_MIN_VERSION" - The Android minimum
	// version code has to be a valid integer.
	//   "UNNECESSARY_ANDROID_PACKAGE_MIN_VERSION" - Android package min
	// version param is not needed, e.g. when
	// 'apn' is missing.
	//   "NOT_URI_ANDROID_LINK" - Android link is not a valid URI.
	//   "UNNECESSARY_ANDROID_LINK" - Android link param is not needed, e.g.
	// when param 'al' and 'link' have
	// the same value..
	//   "NOT_URI_ANDROID_FALLBACK_LINK" - Android fallback link is not a
	// valid URI.
	//   "BAD_URI_SCHEME_ANDROID_FALLBACK_LINK" - Android fallback link has
	// an invalid (non http/https) URI scheme.
	//   "NOT_IN_PROJECT_IOS_BUNDLE_ID" - The iOS bundle ID does not match
	// any in developer's DevConsole project.
	//   "NOT_IN_PROJECT_IPAD_BUNDLE_ID" - The iPad bundle ID does not match
	// any in developer's DevConsole project.
	//   "UNNECESSARY_IOS_URL_SCHEME" - iOS URL scheme is not needed, e.g.
	// when 'ibi' are 'ipbi' are all missing.
	//   "NOT_NUMERIC_IOS_APP_STORE_ID" - iOS app store ID format is
	// incorrect, e.g. not numeric.
	//   "UNNECESSARY_IOS_APP_STORE_ID" - iOS app store ID is not needed.
	//   "NOT_URI_IOS_FALLBACK_LINK" - iOS fallback link is not a valid URI.
	//   "BAD_URI_SCHEME_IOS_FALLBACK_LINK" - iOS fallback link has an
	// invalid (non http/https) URI scheme.
	//   "NOT_URI_IPAD_FALLBACK_LINK" - iPad fallback link is not a valid
	// URI.
	//   "BAD_URI_SCHEME_IPAD_FALLBACK_LINK" - iPad fallback link has an
	// invalid (non http/https) URI scheme.
	//   "BAD_DEBUG_PARAM" - Debug param format is incorrect.
	//   "BAD_AD_PARAM" - isAd param format is incorrect.
	//   "DEPRECATED_PARAM" - Indicates a certain param is deprecated.
	//   "UNRECOGNIZED_PARAM" - Indicates certain paramater is not
	// recognized.
	//   "TOO_LONG_PARAM" - Indicates certain paramater is too long.
	//   "NOT_URI_SOCIAL_IMAGE_LINK" - Social meta tag image link is not a
	// valid URI.
	//   "BAD_URI_SCHEME_SOCIAL_IMAGE_LINK" - Social meta tag image link has
	// an invalid (non http/https) URI scheme.
	//   "NOT_URI_SOCIAL_URL"
	//   "BAD_URI_SCHEME_SOCIAL_URL"
	//   "LINK_LENGTH_TOO_LONG" - Dynamic Link URL length is too long.
	//   "LINK_WITH_FRAGMENTS" - Dynamic Link URL contains fragments.
	//   "NOT_MATCHING_IOS_BUNDLE_ID_AND_STORE_ID" - The iOS bundle ID does
	// not match with the given iOS store ID.
	WarningCode string `json:"warningCode,omitempty"`

	// WarningDocumentLink: The document describing the warning, and helps
	// resolve.
	WarningDocumentLink string `json:"warningDocumentLink,omitempty"`

	// WarningMessage: The warning message to help developers improve their
	// requests.
	WarningMessage string `json:"warningMessage,omitempty"`

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

// GetIosPostInstallAttributionRequest: Request for iSDK to execute
// strong match flow for post-install attribution.
// This is meant for iOS requests only. Requests from other platforms
// will
// not be honored.
type GetIosPostInstallAttributionRequest struct {
	// AppInstallationTime: App installation epoch time
	// (https://en.wikipedia.org/wiki/Unix_time).
	// This is a client signal for a more accurate weak match.
	AppInstallationTime int64 `json:"appInstallationTime,omitempty,string"`

	// BundleId: APP bundle ID.
	BundleId string `json:"bundleId,omitempty"`

	// Device: Device information.
	Device *DeviceInfo `json:"device,omitempty"`

	// IosVersion: iOS version, ie: 9.3.5.
	// Consider adding "build".
	IosVersion string `json:"iosVersion,omitempty"`

	// RetrievalMethod: App post install attribution retrieval information.
	// Disambiguates
	// mechanism (iSDK or developer invoked) to retrieve payload
	// from
	// clicked link.
	//
	// Possible values:
	//   "UNKNOWN_PAYLOAD_RETRIEVAL_METHOD" - Unknown method.
	//   "IMPLICIT_WEAK_MATCH" - iSDK performs a server lookup by device
	// fingerprint in the background
	// when app is first-opened; no API called by developer.
	//   "EXPLICIT_WEAK_MATCH" - iSDK performs a server lookup by device
	// fingerprint upon a dev API call.
	//   "EXPLICIT_STRONG_AFTER_WEAK_MATCH" - iSDK performs a strong match
	// only if weak match is found upon a dev
	// API call.
	RetrievalMethod string `json:"retrievalMethod,omitempty"`

	// SdkVersion: Google SDK version. Version takes the form
	// "$major.$minor.$patch"
	SdkVersion string `json:"sdkVersion,omitempty"`

	// UniqueMatchLinkToCheck: Possible unique matched link that server need
	// to check before performing
	// fingerprint match. If passed link is short server need to expand the
	// link.
	// If link is long server need to vslidate the link.
	UniqueMatchLinkToCheck string `json:"uniqueMatchLinkToCheck,omitempty"`

	// VisualStyle: Strong match page information. Disambiguates between
	// default UI and
	// custom page to present when strong match succeeds/fails to find
	// cookie.
	//
	// Possible values:
	//   "UNKNOWN_VISUAL_STYLE" - Unknown style.
	//   "DEFAULT_STYLE" - Default style.
	//   "CUSTOM_STYLE" - Custom style.
	VisualStyle string `json:"visualStyle,omitempty"`

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

// GetIosPostInstallAttributionResponse: Response for iSDK to execute
// strong match flow for post-install attribution.
type GetIosPostInstallAttributionResponse struct {
	// AppMinimumVersion: The minimum version for app, specified by dev
	// through ?imv= parameter.
	// Return to iSDK to allow app to evaluate if current version meets
	// this.
	AppMinimumVersion string `json:"appMinimumVersion,omitempty"`

	// AttributionConfidence: The confidence of the returned attribution.
	//
	// Possible values:
	//   "UNKNOWN_ATTRIBUTION_CONFIDENCE" - Unset.
	//   "WEAK" - Weak confidence, more than one matching link found or link
	// suspected to
	// be false positive
	//   "DEFAULT" - Default confidence, match based on fingerprint
	//   "UNIQUE" - Unique confidence, match based on "unique match link to
	// check" or other
	// means
	AttributionConfidence string `json:"attributionConfidence,omitempty"`

	// DeepLink: The deep-link attributed post-install via one of several
	// techniques
	// (fingerprint, copy unique).
	DeepLink string `json:"deepLink,omitempty"`

	// ExternalBrowserDestinationLink: User-agent specific custom-scheme
	// URIs for iSDK to open. This will be set
	// according to the user-agent tha the click was originally made in.
	// There is
	// no Safari-equivalent custom-scheme open URLs.
	// ie: googlechrome://www.example.com
	// ie: firefox://open-url?url=http://www.example.com
	// ie: opera-http://example.com
	ExternalBrowserDestinationLink string `json:"externalBrowserDestinationLink,omitempty"`

	// FallbackLink: The link to navigate to update the app if min version
	// is not met.
	// This is either (in order): 1) fallback link (from ?ifl= parameter,
	// if
	// specified by developer) or 2) AppStore URL (from ?isi= parameter,
	// if
	// specified), or 3) the payload link (from required link= parameter).
	FallbackLink string `json:"fallbackLink,omitempty"`

	// InvitationId: Invitation ID attributed post-install via one of
	// several techniques
	// (fingerprint, copy unique).
	InvitationId string `json:"invitationId,omitempty"`

	// IsStrongMatchExecutable: Instruction for iSDK to attemmpt to perform
	// strong match. For instance,
	// if browser does not support/allow cookie or outside of support
	// browsers,
	// this will be false.
	IsStrongMatchExecutable bool `json:"isStrongMatchExecutable,omitempty"`

	// MatchMessage: Describes why match failed, ie: "discarded due to low
	// confidence".
	// This message will be publicly visible.
	MatchMessage string `json:"matchMessage,omitempty"`

	// RequestIpVersion: Which IP version the request was made from.
	//
	// Possible values:
	//   "UNKNOWN_IP_VERSION" - Unset.
	//   "IP_V4" - Request made from an IPv4 IP address.
	//   "IP_V6" - Request made from an IPv6 IP address.
	RequestIpVersion string `json:"requestIpVersion,omitempty"`

	// RequestedLink: Entire FDL (short or long) attributed post-install via
	// one of several
	// techniques (fingerprint, copy unique).
	RequestedLink string `json:"requestedLink,omitempty"`

	// ResolvedLink: The entire FDL, expanded from a short link. It is the
	// same as the
	// requested_link, if it is long. Parameters from this should not
	// be
	// used directly (ie: server can default utm_[campaign|medium|source]
	// to a value when requested_link lack them, server determine the
	// best
	// fallback_link when requested_link specifies >1 fallback links).
	ResolvedLink string `json:"resolvedLink,omitempty"`

	// UtmCampaign: Scion campaign value to be propagated by iSDK to Scion
	// at post-install.
	UtmCampaign string `json:"utmCampaign,omitempty"`

	// UtmContent: Scion content value to be propagated by iSDK to Scion at
	// app-reopen.
	UtmContent string `json:"utmContent,omitempty"`

	// UtmMedium: Scion medium value to be propagated by iSDK to Scion at
	// post-install.
	UtmMedium string `json:"utmMedium,omitempty"`

	// UtmSource: Scion source value to be propagated by iSDK to Scion at
	// post-install.
	UtmSource string `json:"utmSource,omitempty"`

	// UtmTerm: Scion term value to be propagated by iSDK to Scion at
	// app-reopen.
	UtmTerm string `json:"utmTerm,omitempty"`

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

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

// GetIosReopenAttributionRequest: Request for iSDK to get reopen
// attribution for app universal link open
// deeplinking. This endpoint is meant for only iOS requests.
type GetIosReopenAttributionRequest struct {
	// BundleId: APP bundle ID.
	BundleId string `json:"bundleId,omitempty"`

	// RequestedLink: FDL link to be verified from an app universal link
	// open.
	// The FDL link can be one of:
	// 1) short FDL.
	// e.g. <app_code>.page.link/<ddl_id>, or
	// 2) long FDL.
	// e.g. <app_code>.page.link/?{query params}, or
	// 3) Invite FDL.
	// e.g. <app_code>.page.link/i/<invite_id_or_alias>
	RequestedLink string `json:"requestedLink,omitempty"`

	// SdkVersion: Google SDK version. Version takes the form
	// "$major.$minor.$patch"
	SdkVersion string `json:"sdkVersion,omitempty"`

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

// GetIosReopenAttributionResponse: Response for iSDK to get reopen
// attribution for app universal link open
// deeplinking. This endpoint is meant for only iOS requests.
type GetIosReopenAttributionResponse struct {
	// DeepLink: The deep-link attributed the app universal link open. For
	// both regular
	// FDL links and invite FDL links.
	DeepLink string `json:"deepLink,omitempty"`

	// InvitationId: Optional invitation ID, for only invite typed requested
	// FDL links.
	InvitationId string `json:"invitationId,omitempty"`

	// IosMinAppVersion: FDL input value of the "&imv=" parameter, minimum
	// app version to be
	// returned to Google Firebase SDK running on iOS-9.
	IosMinAppVersion string `json:"iosMinAppVersion,omitempty"`

	// ResolvedLink: The entire FDL, expanded from a short link. It is the
	// same as the
	// requested_link, if it is long.
	ResolvedLink string `json:"resolvedLink,omitempty"`

	// UtmCampaign: Scion campaign value to be propagated by iSDK to Scion
	// at app-reopen.
	UtmCampaign string `json:"utmCampaign,omitempty"`

	// UtmContent: Scion content value to be propagated by iSDK to Scion at
	// app-reopen.
	UtmContent string `json:"utmContent,omitempty"`

	// UtmMedium: Scion medium value to be propagated by iSDK to Scion at
	// app-reopen.
	UtmMedium string `json:"utmMedium,omitempty"`

	// UtmSource: Scion source value to be propagated by iSDK to Scion at
	// app-reopen.
	UtmSource string `json:"utmSource,omitempty"`

	// UtmTerm: Scion term value to be propagated by iSDK to Scion at
	// app-reopen.
	UtmTerm string `json:"utmTerm,omitempty"`

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

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

// GooglePlayAnalytics: Parameters for Google Play Campaign
// Measurements.
// [Learn
// more](https://developers.google.com/analytics/dev
// guides/collection/android/v4/campaigns#campaign-params)
type GooglePlayAnalytics struct {
	// Gclid: [AdWords
	// autotagging
	// parameter](https://support.google.com/analytics/answer/103
	// 3981?hl=en); used
	// to measure Google AdWords ads. This value is generated dynamically
	// and
	// should never be modified.
	Gclid string `json:"gclid,omitempty"`

	// UtmCampaign: Campaign name; used for keyword analysis to identify a
	// specific product
	// promotion or strategic campaign.
	UtmCampaign string `json:"utmCampaign,omitempty"`

	// UtmContent: Campaign content; used for A/B testing and
	// content-targeted ads to
	// differentiate ads or links that point to the same URL.
	UtmContent string `json:"utmContent,omitempty"`

	// UtmMedium: Campaign medium; used to identify a medium such as email
	// or cost-per-click.
	UtmMedium string `json:"utmMedium,omitempty"`

	// UtmSource: Campaign source; used to identify a search engine,
	// newsletter, or other
	// source.
	UtmSource string `json:"utmSource,omitempty"`

	// UtmTerm: Campaign term; used with paid search to supply the keywords
	// for ads.
	UtmTerm string `json:"utmTerm,omitempty"`

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

// ITunesConnectAnalytics: Parameters for iTunes Connect App Analytics.
type ITunesConnectAnalytics struct {
	// At: Affiliate token used to create affiliate-coded links.
	At string `json:"at,omitempty"`

	// Ct: Campaign text that developers can optionally add to any link in
	// order to
	// track sales from a specific marketing campaign.
	Ct string `json:"ct,omitempty"`

	// Mt: iTune media types, including music, podcasts, audiobooks and so
	// on.
	Mt string `json:"mt,omitempty"`

	// Pt: Provider token that enables analytics for Dynamic Links from
	// within iTunes
	// Connect.
	Pt string `json:"pt,omitempty"`

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

// IosInfo: iOS related attributes to the Dynamic Link..
type IosInfo struct {
	// IosAppStoreId: iOS App Store ID.
	IosAppStoreId string `json:"iosAppStoreId,omitempty"`

	// IosBundleId: iOS bundle ID of the app.
	IosBundleId string `json:"iosBundleId,omitempty"`

	// IosCustomScheme: Custom (destination) scheme to use for iOS. By
	// default, we’ll use the
	// bundle ID as the custom scheme. Developer can override this behavior
	// using
	// this param.
	IosCustomScheme string `json:"iosCustomScheme,omitempty"`

	// IosFallbackLink: Link to open on iOS if the app is not installed.
	IosFallbackLink string `json:"iosFallbackLink,omitempty"`

	// IosIpadBundleId: iPad bundle ID of the app.
	IosIpadBundleId string `json:"iosIpadBundleId,omitempty"`

	// IosIpadFallbackLink: If specified, this overrides the
	// ios_fallback_link value on iPads.
	IosIpadFallbackLink string `json:"iosIpadFallbackLink,omitempty"`

	// IosMinimumVersion: iOS minimum version.
	IosMinimumVersion string `json:"iosMinimumVersion,omitempty"`

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

// ManagedShortLink: Managed Short Link.
type ManagedShortLink struct {
	// CreationTime: Creation timestamp of the short link.
	CreationTime string `json:"creationTime,omitempty"`

	// FlaggedAttribute: Attributes that have been flagged about this short
	// url.
	//
	// Possible values:
	//   "UNSPECIFIED_ATTRIBUTE" - Indicates that no attributes were found
	// for this short url.
	//   "SPAM" - Indicates that short url has been flagged by AbuseIAm team
	// as spam.
	FlaggedAttribute []string `json:"flaggedAttribute,omitempty"`

	// Info: Full Dyamic Link info
	Info *DynamicLinkInfo `json:"info,omitempty"`

	// Link: Short durable link url, for example,
	// "https://sample.app.goo.gl/xyz123".
	//
	// Required.
	Link string `json:"link,omitempty"`

	// LinkName: Link name defined by the creator.
	//
	// Required.
	LinkName string `json:"linkName,omitempty"`

	// Visibility: Visibility status of link.
	//
	// Possible values:
	//   "UNSPECIFIED_VISIBILITY" - Visibility of the link is not specified.
	//   "UNARCHIVED" - Link created in console and should be shown in
	// console.
	//   "ARCHIVED" - Link created in console and should not be shown in
	// console (but can
	// be shown in the console again if it is unarchived).
	//   "NEVER_SHOWN" - Link created outside of console and should never be
	// shown in console.
	Visibility string `json:"visibility,omitempty"`

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

// NavigationInfo: Information of navigation behavior.
type NavigationInfo struct {
	// EnableForcedRedirect: If this option is on, FDL click will be forced
	// to redirect rather than
	// show an interstitial page.
	EnableForcedRedirect bool `json:"enableForcedRedirect,omitempty"`

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

// SocialMetaTagInfo: Parameters for social meta tag params.
// Used to set meta tag data for link previews on social sites.
type SocialMetaTagInfo struct {
	// SocialDescription: A short description of the link. Optional.
	SocialDescription string `json:"socialDescription,omitempty"`

	// SocialImageLink: An image url string. Optional.
	SocialImageLink string `json:"socialImageLink,omitempty"`

	// SocialTitle: Title to be displayed. Optional.
	SocialTitle string `json:"socialTitle,omitempty"`

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

// Suffix: Short Dynamic Link suffix.
type Suffix struct {
	// CustomSuffix: Only applies to Option.CUSTOM.
	CustomSuffix string `json:"customSuffix,omitempty"`

	// Option: Suffix option.
	//
	// Possible values:
	//   "OPTION_UNSPECIFIED" - The suffix option is not specified, performs
	// as UNGUESSABLE .
	//   "UNGUESSABLE" - Short Dynamic Link suffix is a base62 [0-9A-Za-z]
	// encoded string of
	// a random generated 96 bit random number, which has a length of 17
	// chars.
	// For example, "nlAR8U4SlKRZw1cb2".
	// It prevents other people from guessing and crawling short Dynamic
	// Links
	// that contain personal identifiable information.
	//   "SHORT" - Short Dynamic Link suffix is a base62 [0-9A-Za-z] string
	// starting with a
	// length of 4 chars. the length will increase when all the space
	// is
	// occupied.
	//   "CUSTOM" - Custom DDL suffix is a client specified string, for
	// example,
	// "buy2get1free".
	// NOTE: custom suffix should only be available to managed short
	// link
	// creation
	Option string `json:"option,omitempty"`

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

// method id "firebasedynamiclinks.managedShortLinks.create":

type ManagedShortLinksCreateCall struct {
	s                             *Service
	createmanagedshortlinkrequest *CreateManagedShortLinkRequest
	urlParams_                    gensupport.URLParams
	ctx_                          context.Context
	header_                       http.Header
}

// Create: Creates a managed short Dynamic Link given either a valid
// long Dynamic Link
// or details such as Dynamic Link domain, Android and iOS app
// information.
// The created short Dynamic Link will not expire.
//
// This differs from CreateShortDynamicLink in the following ways:
//   - The request will also contain a name for the link (non unique
// name
//     for the front end).
//   - The response must be authenticated with an auth token (generated
// with
//     the admin service account).
//   - The link will appear in the FDL list of links in the console
// front end.
//
// The Dynamic Link domain in the request must be owned by
// requester's
// Firebase project.
func (r *ManagedShortLinksService) Create(createmanagedshortlinkrequest *CreateManagedShortLinkRequest) *ManagedShortLinksCreateCall {
	c := &ManagedShortLinksCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.createmanagedshortlinkrequest = createmanagedshortlinkrequest
	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 *ManagedShortLinksCreateCall) Fields(s ...googleapi.Field) *ManagedShortLinksCreateCall {
	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 *ManagedShortLinksCreateCall) Context(ctx context.Context) *ManagedShortLinksCreateCall {
	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 *ManagedShortLinksCreateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ManagedShortLinksCreateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200422")
	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.createmanagedshortlinkrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/managedShortLinks:create")
	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 "firebasedynamiclinks.managedShortLinks.create" call.
// Exactly one of *CreateManagedShortLinkResponse or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *CreateManagedShortLinkResponse.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 *ManagedShortLinksCreateCall) Do(opts ...googleapi.CallOption) (*CreateManagedShortLinkResponse, 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 := &CreateManagedShortLinkResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Creates a managed short Dynamic Link given either a valid long Dynamic Link\nor details such as Dynamic Link domain, Android and iOS app information.\nThe created short Dynamic Link will not expire.\n\nThis differs from CreateShortDynamicLink in the following ways:\n  - The request will also contain a name for the link (non unique name\n    for the front end).\n  - The response must be authenticated with an auth token (generated with\n    the admin service account).\n  - The link will appear in the FDL list of links in the console front end.\n\nThe Dynamic Link domain in the request must be owned by requester's\nFirebase project.",
	//   "flatPath": "v1/managedShortLinks:create",
	//   "httpMethod": "POST",
	//   "id": "firebasedynamiclinks.managedShortLinks.create",
	//   "parameterOrder": [],
	//   "parameters": {},
	//   "path": "v1/managedShortLinks:create",
	//   "request": {
	//     "$ref": "CreateManagedShortLinkRequest"
	//   },
	//   "response": {
	//     "$ref": "CreateManagedShortLinkResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/firebase"
	//   ]
	// }

}

// method id "firebasedynamiclinks.shortLinks.create":

type ShortLinksCreateCall struct {
	s                             *Service
	createshortdynamiclinkrequest *CreateShortDynamicLinkRequest
	urlParams_                    gensupport.URLParams
	ctx_                          context.Context
	header_                       http.Header
}

// Create: Creates a short Dynamic Link given either a valid long
// Dynamic Link or
// details such as Dynamic Link domain, Android and iOS app
// information.
// The created short Dynamic Link will not expire.
//
// Repeated calls with the same long Dynamic Link or Dynamic Link
// information
// will produce the same short Dynamic Link.
//
// The Dynamic Link domain in the request must be owned by
// requester's
// Firebase project.
func (r *ShortLinksService) Create(createshortdynamiclinkrequest *CreateShortDynamicLinkRequest) *ShortLinksCreateCall {
	c := &ShortLinksCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.createshortdynamiclinkrequest = createshortdynamiclinkrequest
	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 *ShortLinksCreateCall) Fields(s ...googleapi.Field) *ShortLinksCreateCall {
	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 *ShortLinksCreateCall) Context(ctx context.Context) *ShortLinksCreateCall {
	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 *ShortLinksCreateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ShortLinksCreateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200422")
	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.createshortdynamiclinkrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/shortLinks")
	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 "firebasedynamiclinks.shortLinks.create" call.
// Exactly one of *CreateShortDynamicLinkResponse or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *CreateShortDynamicLinkResponse.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 *ShortLinksCreateCall) Do(opts ...googleapi.CallOption) (*CreateShortDynamicLinkResponse, 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 := &CreateShortDynamicLinkResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Creates a short Dynamic Link given either a valid long Dynamic Link or\ndetails such as Dynamic Link domain, Android and iOS app information.\nThe created short Dynamic Link will not expire.\n\nRepeated calls with the same long Dynamic Link or Dynamic Link information\nwill produce the same short Dynamic Link.\n\nThe Dynamic Link domain in the request must be owned by requester's\nFirebase project.",
	//   "flatPath": "v1/shortLinks",
	//   "httpMethod": "POST",
	//   "id": "firebasedynamiclinks.shortLinks.create",
	//   "parameterOrder": [],
	//   "parameters": {},
	//   "path": "v1/shortLinks",
	//   "request": {
	//     "$ref": "CreateShortDynamicLinkRequest"
	//   },
	//   "response": {
	//     "$ref": "CreateShortDynamicLinkResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/firebase"
	//   ]
	// }

}

// method id "firebasedynamiclinks.getLinkStats":

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

// GetLinkStats: Fetches analytics stats of a short Dynamic Link for a
// given
// duration. Metrics include number of clicks, redirects, installs,
// app first opens, and app reopens.
func (r *V1Service) GetLinkStats(dynamicLink string) *V1GetLinkStatsCall {
	c := &V1GetLinkStatsCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.dynamicLink = dynamicLink
	return c
}

// DurationDays sets the optional parameter "durationDays": The span of
// time requested in days.
func (c *V1GetLinkStatsCall) DurationDays(durationDays int64) *V1GetLinkStatsCall {
	c.urlParams_.Set("durationDays", fmt.Sprint(durationDays))
	return c
}

// SdkVersion sets the optional parameter "sdkVersion": Google SDK
// version. Version takes the form "$major.$minor.$patch"
func (c *V1GetLinkStatsCall) SdkVersion(sdkVersion string) *V1GetLinkStatsCall {
	c.urlParams_.Set("sdkVersion", sdkVersion)
	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 *V1GetLinkStatsCall) Fields(s ...googleapi.Field) *V1GetLinkStatsCall {
	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 *V1GetLinkStatsCall) IfNoneMatch(entityTag string) *V1GetLinkStatsCall {
	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 *V1GetLinkStatsCall) Context(ctx context.Context) *V1GetLinkStatsCall {
	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 *V1GetLinkStatsCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

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

// Do executes the "firebasedynamiclinks.getLinkStats" call.
// Exactly one of *DynamicLinkStats or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *DynamicLinkStats.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 *V1GetLinkStatsCall) Do(opts ...googleapi.CallOption) (*DynamicLinkStats, 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 := &DynamicLinkStats{
		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": "Fetches analytics stats of a short Dynamic Link for a given\nduration. Metrics include number of clicks, redirects, installs,\napp first opens, and app reopens.",
	//   "flatPath": "v1/{dynamicLink}/linkStats",
	//   "httpMethod": "GET",
	//   "id": "firebasedynamiclinks.getLinkStats",
	//   "parameterOrder": [
	//     "dynamicLink"
	//   ],
	//   "parameters": {
	//     "durationDays": {
	//       "description": "The span of time requested in days.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "dynamicLink": {
	//       "description": "Dynamic Link URL. e.g. https://abcd.app.goo.gl/wxyz",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "sdkVersion": {
	//       "description": "Google SDK version. Version takes the form \"$major.$minor.$patch\"",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{dynamicLink}/linkStats",
	//   "response": {
	//     "$ref": "DynamicLinkStats"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/firebase"
	//   ]
	// }

}

// method id "firebasedynamiclinks.installAttribution":

type V1InstallAttributionCall struct {
	s                                   *Service
	getiospostinstallattributionrequest *GetIosPostInstallAttributionRequest
	urlParams_                          gensupport.URLParams
	ctx_                                context.Context
	header_                             http.Header
}

// InstallAttribution: Get iOS strong/weak-match info for post-install
// attribution.
func (r *V1Service) InstallAttribution(getiospostinstallattributionrequest *GetIosPostInstallAttributionRequest) *V1InstallAttributionCall {
	c := &V1InstallAttributionCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.getiospostinstallattributionrequest = getiospostinstallattributionrequest
	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 *V1InstallAttributionCall) Fields(s ...googleapi.Field) *V1InstallAttributionCall {
	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 *V1InstallAttributionCall) Context(ctx context.Context) *V1InstallAttributionCall {
	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 *V1InstallAttributionCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *V1InstallAttributionCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200422")
	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.getiospostinstallattributionrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/installAttribution")
	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 "firebasedynamiclinks.installAttribution" call.
// Exactly one of *GetIosPostInstallAttributionResponse or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *GetIosPostInstallAttributionResponse.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 *V1InstallAttributionCall) Do(opts ...googleapi.CallOption) (*GetIosPostInstallAttributionResponse, 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 := &GetIosPostInstallAttributionResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Get iOS strong/weak-match info for post-install attribution.",
	//   "flatPath": "v1/installAttribution",
	//   "httpMethod": "POST",
	//   "id": "firebasedynamiclinks.installAttribution",
	//   "parameterOrder": [],
	//   "parameters": {},
	//   "path": "v1/installAttribution",
	//   "request": {
	//     "$ref": "GetIosPostInstallAttributionRequest"
	//   },
	//   "response": {
	//     "$ref": "GetIosPostInstallAttributionResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/firebase"
	//   ]
	// }

}

// method id "firebasedynamiclinks.reopenAttribution":

type V1ReopenAttributionCall struct {
	s                              *Service
	getiosreopenattributionrequest *GetIosReopenAttributionRequest
	urlParams_                     gensupport.URLParams
	ctx_                           context.Context
	header_                        http.Header
}

// ReopenAttribution: Get iOS reopen attribution for app universal link
// open deeplinking.
func (r *V1Service) ReopenAttribution(getiosreopenattributionrequest *GetIosReopenAttributionRequest) *V1ReopenAttributionCall {
	c := &V1ReopenAttributionCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.getiosreopenattributionrequest = getiosreopenattributionrequest
	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 *V1ReopenAttributionCall) Fields(s ...googleapi.Field) *V1ReopenAttributionCall {
	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 *V1ReopenAttributionCall) Context(ctx context.Context) *V1ReopenAttributionCall {
	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 *V1ReopenAttributionCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *V1ReopenAttributionCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200422")
	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.getiosreopenattributionrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/reopenAttribution")
	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 "firebasedynamiclinks.reopenAttribution" call.
// Exactly one of *GetIosReopenAttributionResponse or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *GetIosReopenAttributionResponse.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 *V1ReopenAttributionCall) Do(opts ...googleapi.CallOption) (*GetIosReopenAttributionResponse, 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 := &GetIosReopenAttributionResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Get iOS reopen attribution for app universal link open deeplinking.",
	//   "flatPath": "v1/reopenAttribution",
	//   "httpMethod": "POST",
	//   "id": "firebasedynamiclinks.reopenAttribution",
	//   "parameterOrder": [],
	//   "parameters": {},
	//   "path": "v1/reopenAttribution",
	//   "request": {
	//     "$ref": "GetIosReopenAttributionRequest"
	//   },
	//   "response": {
	//     "$ref": "GetIosReopenAttributionResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/firebase"
	//   ]
	// }

}
