// 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 digitalassetlinks provides access to the Digital Asset Links API.
//
// For product documentation, see: https://developers.google.com/digital-asset-links/
//
// Creating a client
//
// Usage example:
//
//   import "google.golang.org/api/digitalassetlinks/v1"
//   ...
//   ctx := context.Background()
//   digitalassetlinksService, err := digitalassetlinks.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:
//
//   digitalassetlinksService, err := digitalassetlinks.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, ...)
//   digitalassetlinksService, err := digitalassetlinks.NewService(ctx, option.WithTokenSource(config.TokenSource(ctx, token)))
//
// See https://godoc.org/google.golang.org/api/option/ for details on options.
package digitalassetlinks // import "google.golang.org/api/digitalassetlinks/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 = "digitalassetlinks:v1"
const apiName = "digitalassetlinks"
const apiVersion = "v1"
const basePath = "https://digitalassetlinks.googleapis.com/"

// NewService creates a new Service.
func NewService(ctx context.Context, opts ...option.ClientOption) (*Service, error) {
	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.Assetlinks = NewAssetlinksService(s)
	s.Statements = NewStatementsService(s)
	return s, nil
}

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

	Assetlinks *AssetlinksService

	Statements *StatementsService
}

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

func NewAssetlinksService(s *Service) *AssetlinksService {
	rs := &AssetlinksService{s: s}
	return rs
}

type AssetlinksService struct {
	s *Service
}

func NewStatementsService(s *Service) *StatementsService {
	rs := &StatementsService{s: s}
	return rs
}

type StatementsService struct {
	s *Service
}

// AndroidAppAsset: Describes an android app asset.
type AndroidAppAsset struct {
	// Certificate: Because there is no global enforcement of package name
	// uniqueness, we also
	// require a signing certificate, which in combination with the package
	// name
	// uniquely identifies an app.
	//
	// Some apps' signing keys are rotated, so they may be signed by
	// different
	// keys over time.  We treat these as distinct assets, since we use
	// (package
	// name, cert) as the unique ID.  This should not normally pose any
	// problems
	// as both versions of the app will make the same or similar
	// statements.
	// Other assets making statements about the app will have to be updated
	// when a
	// key is rotated, however.
	//
	// (Note that the syntaxes for publishing and querying for statements
	// contain
	// syntactic sugar to easily let you specify apps that are known by
	// multiple
	// certificates.)
	// REQUIRED
	Certificate *CertificateInfo `json:"certificate,omitempty"`

	// PackageName: Android App assets are naturally identified by their
	// Java package name.
	// For example, the Google Maps app uses the package
	// name
	// `com.google.android.apps.maps`.
	// REQUIRED
	PackageName string `json:"packageName,omitempty"`

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

// Asset: Uniquely identifies an asset.
//
// A digital asset is an identifiable and addressable online entity
// that
// typically provides some service or content.  Examples of assets are
// websites,
// Android apps, Twitter feeds, and Plus Pages.
type Asset struct {
	// AndroidApp: Set if this is an Android App asset.
	AndroidApp *AndroidAppAsset `json:"androidApp,omitempty"`

	// Web: Set if this is a web asset.
	Web *WebAsset `json:"web,omitempty"`

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

// CertificateInfo: Describes an X509 certificate.
type CertificateInfo struct {
	// Sha256Fingerprint: The uppercase SHA-265 fingerprint of the
	// certificate.  From the PEM
	//  certificate, it can be acquired like this:
	//
	//     $ keytool -printcert -file $CERTFILE | grep SHA256:
	//     SHA256: 14:6D:E9:83:C5:73:06:50:D8:EE:B9:95:2F:34:FC:64:16:A0:83:
	// \
	//         42:E6:1D:BE:A8:8A:04:96:B2:3F:CF:44:E5
	//
	// or like this:
	//
	//     $ openssl x509 -in $CERTFILE -noout -fingerprint -sha256
	//     SHA256
	// Fingerprint=14:6D:E9:83:C5:73:06:50:D8:EE:B9:95:2F:34:FC:64: \
	//         16:A0:83:42:E6:1D:BE:A8:8A:04:96:B2:3F:CF:44:E5
	//
	// In this example, the contents of this field would be
	// `14:6D:E9:83:C5:73:
	// 06:50:D8:EE:B9:95:2F:34:FC:64:16:A0:83:42:E6:1D:BE
	// :A8:8A:04:96:B2:3F:CF:
	// 44:E5`.
	//
	// If these tools are not available to you, you can convert the
	// PEM
	// certificate into the DER format, compute the SHA-256 hash of that
	// string
	// and represent the result as a hexstring (that is, uppercase
	// hexadecimal
	// representations of each octet, separated by colons).
	Sha256Fingerprint string `json:"sha256Fingerprint,omitempty"`

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

// CheckResponse: Response message for the CheckAssetLinks call.
type CheckResponse struct {
	// DebugString: Human-readable message containing information intended
	// to help end users
	// understand, reproduce and debug the result.
	//
	//
	// The message will be in English and we are currently not planning to
	// offer
	// any translations.
	//
	// Please note that no guarantees are made about the contents or format
	// of
	// this string.  Any aspect of it may be subject to change without
	// notice.
	// You should not attempt to programmatically parse this data.
	// For
	// programmatic access, use the error_code field below.
	DebugString string `json:"debugString,omitempty"`

	// ErrorCode: Error codes that describe the result of the Check
	// operation.
	//
	// Possible values:
	//   "ERROR_CODE_UNSPECIFIED"
	//   "ERROR_CODE_INVALID_QUERY" - Unable to parse query.
	//   "ERROR_CODE_FETCH_ERROR" - Unable to fetch the asset links data.
	//   "ERROR_CODE_FAILED_SSL_VALIDATION" - Invalid HTTPS certificate .
	//   "ERROR_CODE_REDIRECT" - HTTP redirects (e.g, 301) are not allowed.
	//   "ERROR_CODE_TOO_LARGE" - Asset links data exceeds maximum size.
	//   "ERROR_CODE_MALFORMED_HTTP_RESPONSE" - Can't parse HTTP response.
	//   "ERROR_CODE_WRONG_CONTENT_TYPE" - HTTP Content-type should be
	// application/json.
	//   "ERROR_CODE_MALFORMED_CONTENT" - JSON content is malformed.
	//   "ERROR_CODE_SECURE_ASSET_INCLUDES_INSECURE" - A secure asset
	// includes an insecure asset (security downgrade).
	//   "ERROR_CODE_FETCH_BUDGET_EXHAUSTED" - Too many includes (maybe a
	// loop).
	ErrorCode []string `json:"errorCode,omitempty"`

	// Linked: Set to true if the assets specified in the request are linked
	// by the
	// relation specified in the request.
	Linked bool `json:"linked,omitempty"`

	// MaxAge: From serving time, how much longer the response should be
	// considered valid
	// barring further updates.
	// REQUIRED
	MaxAge string `json:"maxAge,omitempty"`

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

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

// ListResponse: Response message for the List call.
type ListResponse struct {
	// DebugString: Human-readable message containing information intended
	// to help end users
	// understand, reproduce and debug the result.
	//
	//
	// The message will be in English and we are currently not planning to
	// offer
	// any translations.
	//
	// Please note that no guarantees are made about the contents or format
	// of
	// this string.  Any aspect of it may be subject to change without
	// notice.
	// You should not attempt to programmatically parse this data.
	// For
	// programmatic access, use the error_code field below.
	DebugString string `json:"debugString,omitempty"`

	// ErrorCode: Error codes that describe the result of the List
	// operation.
	//
	// Possible values:
	//   "ERROR_CODE_UNSPECIFIED"
	//   "ERROR_CODE_INVALID_QUERY" - Unable to parse query.
	//   "ERROR_CODE_FETCH_ERROR" - Unable to fetch the asset links data.
	//   "ERROR_CODE_FAILED_SSL_VALIDATION" - Invalid HTTPS certificate .
	//   "ERROR_CODE_REDIRECT" - HTTP redirects (e.g, 301) are not allowed.
	//   "ERROR_CODE_TOO_LARGE" - Asset links data exceeds maximum size.
	//   "ERROR_CODE_MALFORMED_HTTP_RESPONSE" - Can't parse HTTP response.
	//   "ERROR_CODE_WRONG_CONTENT_TYPE" - HTTP Content-type should be
	// application/json.
	//   "ERROR_CODE_MALFORMED_CONTENT" - JSON content is malformed.
	//   "ERROR_CODE_SECURE_ASSET_INCLUDES_INSECURE" - A secure asset
	// includes an insecure asset (security downgrade).
	//   "ERROR_CODE_FETCH_BUDGET_EXHAUSTED" - Too many includes (maybe a
	// loop).
	ErrorCode []string `json:"errorCode,omitempty"`

	// MaxAge: From serving time, how much longer the response should be
	// considered valid
	// barring further updates.
	// REQUIRED
	MaxAge string `json:"maxAge,omitempty"`

	// Statements: A list of all the matching statements that have been
	// found.
	Statements []*Statement `json:"statements,omitempty"`

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

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

// Statement: Describes a reliable statement that has been made about
// the relationship
// between a source asset and a target asset.
//
// Statements are always made by the source asset, either directly or
// by
// delegating to a statement list that is stored elsewhere.
//
// For more detailed definitions of statements and assets, please
// refer
// to our [API documentation
// landing
// page](/digital-asset-links/v1/getting-started).
type Statement struct {
	// Relation: The relation identifies the use of the statement as
	// intended by the source
	// asset's owner (that is, the person or entity who issued the
	// statement).
	// Every complete statement has a relation.
	//
	// We identify relations with strings of the format `<kind>/<detail>`,
	// where
	// `<kind>` must be one of a set of pre-defined purpose categories,
	// and
	// `<detail>` is a free-form lowercase alphanumeric string that
	// describes the
	// specific use case of the statement.
	//
	// Refer to [our API
	// documentation](/digital-asset-links/v1/relation-strings)
	// for the current list of supported relations.
	//
	// Example: `delegate_permission/common.handle_all_urls`
	// REQUIRED
	Relation string `json:"relation,omitempty"`

	// Source: Every statement has a source asset.
	// REQUIRED
	Source *Asset `json:"source,omitempty"`

	// Target: Every statement has a target asset.
	// REQUIRED
	Target *Asset `json:"target,omitempty"`

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

// WebAsset: Describes a web asset.
type WebAsset struct {
	// Site: Web assets are identified by a URL that contains only the
	// scheme, hostname
	// and port parts.  The format is
	//
	//     http[s]://<hostname>[:<port>]
	//
	// Hostnames must be fully qualified: they must end in a single
	// period
	// (".").
	//
	// Only the schemes "http" and "https" are currently allowed.
	//
	// Port numbers are given as a decimal number, and they must be omitted
	// if the
	// standard port numbers are used: 80 for http and 443 for https.
	//
	// We call this limited URL the "site".  All URLs that share the same
	// scheme,
	// hostname and port are considered to be a part of the site and thus
	// belong
	// to the web asset.
	//
	// Example: the asset with the site `https://www.google.com` contains
	// all
	// these URLs:
	//
	//   *   `https://www.google.com/`
	//   *   `https://www.google.com:443/`
	//   *   `https://www.google.com/foo`
	//   *   `https://www.google.com/foo?bar`
	//   *   `https://www.google.com/foo#bar`
	//   *   `https://user@password:www.google.com/`
	//
	// But it does not contain these URLs:
	//
	//   *   `http://www.google.com/`       (wrong scheme)
	//   *   `https://google.com/`          (hostname does not match)
	//   *   `https://www.google.com:444/`  (port does not match)
	// REQUIRED
	Site string `json:"site,omitempty"`

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

// method id "digitalassetlinks.assetlinks.check":

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

// Check: Determines whether the specified (directional) relationship
// exists between
// the specified source and target assets.
//
// The relation describes the intent of the link between the two assets
// as
// claimed by the source asset.  An example for such relationships is
// the
// delegation of privileges or permissions.
//
// This command is most often used by infrastructure systems to
// check
// preconditions for an action.  For example, a client may want to know
// if it
// is OK to send a web URL to a particular mobile app instead. The
// client can
// check for the relevant asset link from the website to the mobile app
// to
// decide if the operation should be allowed.
//
// A note about security: if you specify a secure asset as the source,
// such as
// an HTTPS website or an Android app, the API will ensure that
// any
// statements used to generate the response have been made in a secure
// way by
// the owner of that asset.  Conversely, if the source asset is an
// insecure
// HTTP website (that is, the URL starts with `http://` instead
// of
// `https://`), the API cannot verify its statements securely, and it is
// not
// possible to ensure that the website's statements have not been
// altered by a
// third party.  For more information, see the [Digital Asset Links
// technical
// design
// specification](https://github.com/google/digitalasset
// links/blob/master/well-known/details.md).
func (r *AssetlinksService) Check() *AssetlinksCheckCall {
	c := &AssetlinksCheckCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	return c
}

// Relation sets the optional parameter "relation": Query string for the
// relation.
//
// We identify relations with strings of the format `<kind>/<detail>`,
// where
// `<kind>` must be one of a set of pre-defined purpose categories,
// and
// `<detail>` is a free-form lowercase alphanumeric string that
// describes the
// specific use case of the statement.
//
// Refer to [our API
// documentation](/digital-asset-links/v1/relation-strings)
// for the current list of supported relations.
//
// For a query to match an asset link, both the query's and the asset
// link's
// relation strings must match exactly.
//
// Example: A query with relation
// `delegate_permission/common.handle_all_urls`
// matches an asset link with
// relation
// `delegate_permission/common.handle_all_urls`.
func (c *AssetlinksCheckCall) Relation(relation string) *AssetlinksCheckCall {
	c.urlParams_.Set("relation", relation)
	return c
}

// SourceAndroidAppCertificateSha256Fingerprint sets the optional
// parameter "source.androidApp.certificate.sha256Fingerprint": The
// uppercase SHA-265 fingerprint of the certificate.  From the PEM
//  certificate, it can be acquired like this:
//
//     $ keytool -printcert -file $CERTFILE | grep SHA256:
//     SHA256: 14:6D:E9:83:C5:73:06:50:D8:EE:B9:95:2F:34:FC:64:16:A0:83:
// \
//         42:E6:1D:BE:A8:8A:04:96:B2:3F:CF:44:E5
//
// or like this:
//
//     $ openssl x509 -in $CERTFILE -noout -fingerprint -sha256
//     SHA256
// Fingerprint=14:6D:E9:83:C5:73:06:50:D8:EE:B9:95:2F:34:FC:64: \
//         16:A0:83:42:E6:1D:BE:A8:8A:04:96:B2:3F:CF:44:E5
//
// In this example, the contents of this field would be
// `14:6D:E9:83:C5:73:
// 06:50:D8:EE:B9:95:2F:34:FC:64:16:A0:83:42:E6:1D:BE
// :A8:8A:04:96:B2:3F:CF:
// 44:E5`.
//
// If these tools are not available to you, you can convert the
// PEM
// certificate into the DER format, compute the SHA-256 hash of that
// string
// and represent the result as a hexstring (that is, uppercase
// hexadecimal
// representations of each octet, separated by colons).
func (c *AssetlinksCheckCall) SourceAndroidAppCertificateSha256Fingerprint(sourceAndroidAppCertificateSha256Fingerprint string) *AssetlinksCheckCall {
	c.urlParams_.Set("source.androidApp.certificate.sha256Fingerprint", sourceAndroidAppCertificateSha256Fingerprint)
	return c
}

// SourceAndroidAppPackageName sets the optional parameter
// "source.androidApp.packageName": Android App assets are naturally
// identified by their Java package name.
// For example, the Google Maps app uses the package
// name
// `com.google.android.apps.maps`.
// REQUIRED
func (c *AssetlinksCheckCall) SourceAndroidAppPackageName(sourceAndroidAppPackageName string) *AssetlinksCheckCall {
	c.urlParams_.Set("source.androidApp.packageName", sourceAndroidAppPackageName)
	return c
}

// SourceWebSite sets the optional parameter "source.web.site": Web
// assets are identified by a URL that contains only the scheme,
// hostname
// and port parts.  The format is
//
//     http[s]://<hostname>[:<port>]
//
// Hostnames must be fully qualified: they must end in a single
// period
// (".").
//
// Only the schemes "http" and "https" are currently allowed.
//
// Port numbers are given as a decimal number, and they must be omitted
// if the
// standard port numbers are used: 80 for http and 443 for https.
//
// We call this limited URL the "site".  All URLs that share the same
// scheme,
// hostname and port are considered to be a part of the site and thus
// belong
// to the web asset.
//
// Example: the asset with the site `https://www.google.com` contains
// all
// these URLs:
//
//   *   `https://www.google.com/`
//   *   `https://www.google.com:443/`
//   *   `https://www.google.com/foo`
//   *   `https://www.google.com/foo?bar`
//   *   `https://www.google.com/foo#bar`
//   *   `https://user@password:www.google.com/`
//
// But it does not contain these URLs:
//
//   *   `http://www.google.com/`       (wrong scheme)
//   *   `https://google.com/`          (hostname does not match)
//   *   `https://www.google.com:444/`  (port does not match)
// REQUIRED
func (c *AssetlinksCheckCall) SourceWebSite(sourceWebSite string) *AssetlinksCheckCall {
	c.urlParams_.Set("source.web.site", sourceWebSite)
	return c
}

// TargetAndroidAppCertificateSha256Fingerprint sets the optional
// parameter "target.androidApp.certificate.sha256Fingerprint": The
// uppercase SHA-265 fingerprint of the certificate.  From the PEM
//  certificate, it can be acquired like this:
//
//     $ keytool -printcert -file $CERTFILE | grep SHA256:
//     SHA256: 14:6D:E9:83:C5:73:06:50:D8:EE:B9:95:2F:34:FC:64:16:A0:83:
// \
//         42:E6:1D:BE:A8:8A:04:96:B2:3F:CF:44:E5
//
// or like this:
//
//     $ openssl x509 -in $CERTFILE -noout -fingerprint -sha256
//     SHA256
// Fingerprint=14:6D:E9:83:C5:73:06:50:D8:EE:B9:95:2F:34:FC:64: \
//         16:A0:83:42:E6:1D:BE:A8:8A:04:96:B2:3F:CF:44:E5
//
// In this example, the contents of this field would be
// `14:6D:E9:83:C5:73:
// 06:50:D8:EE:B9:95:2F:34:FC:64:16:A0:83:42:E6:1D:BE
// :A8:8A:04:96:B2:3F:CF:
// 44:E5`.
//
// If these tools are not available to you, you can convert the
// PEM
// certificate into the DER format, compute the SHA-256 hash of that
// string
// and represent the result as a hexstring (that is, uppercase
// hexadecimal
// representations of each octet, separated by colons).
func (c *AssetlinksCheckCall) TargetAndroidAppCertificateSha256Fingerprint(targetAndroidAppCertificateSha256Fingerprint string) *AssetlinksCheckCall {
	c.urlParams_.Set("target.androidApp.certificate.sha256Fingerprint", targetAndroidAppCertificateSha256Fingerprint)
	return c
}

// TargetAndroidAppPackageName sets the optional parameter
// "target.androidApp.packageName": Android App assets are naturally
// identified by their Java package name.
// For example, the Google Maps app uses the package
// name
// `com.google.android.apps.maps`.
// REQUIRED
func (c *AssetlinksCheckCall) TargetAndroidAppPackageName(targetAndroidAppPackageName string) *AssetlinksCheckCall {
	c.urlParams_.Set("target.androidApp.packageName", targetAndroidAppPackageName)
	return c
}

// TargetWebSite sets the optional parameter "target.web.site": Web
// assets are identified by a URL that contains only the scheme,
// hostname
// and port parts.  The format is
//
//     http[s]://<hostname>[:<port>]
//
// Hostnames must be fully qualified: they must end in a single
// period
// (".").
//
// Only the schemes "http" and "https" are currently allowed.
//
// Port numbers are given as a decimal number, and they must be omitted
// if the
// standard port numbers are used: 80 for http and 443 for https.
//
// We call this limited URL the "site".  All URLs that share the same
// scheme,
// hostname and port are considered to be a part of the site and thus
// belong
// to the web asset.
//
// Example: the asset with the site `https://www.google.com` contains
// all
// these URLs:
//
//   *   `https://www.google.com/`
//   *   `https://www.google.com:443/`
//   *   `https://www.google.com/foo`
//   *   `https://www.google.com/foo?bar`
//   *   `https://www.google.com/foo#bar`
//   *   `https://user@password:www.google.com/`
//
// But it does not contain these URLs:
//
//   *   `http://www.google.com/`       (wrong scheme)
//   *   `https://google.com/`          (hostname does not match)
//   *   `https://www.google.com:444/`  (port does not match)
// REQUIRED
func (c *AssetlinksCheckCall) TargetWebSite(targetWebSite string) *AssetlinksCheckCall {
	c.urlParams_.Set("target.web.site", targetWebSite)
	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 *AssetlinksCheckCall) Fields(s ...googleapi.Field) *AssetlinksCheckCall {
	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 *AssetlinksCheckCall) IfNoneMatch(entityTag string) *AssetlinksCheckCall {
	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 *AssetlinksCheckCall) Context(ctx context.Context) *AssetlinksCheckCall {
	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 *AssetlinksCheckCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AssetlinksCheckCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200317")
	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/assetlinks:check")
	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 "digitalassetlinks.assetlinks.check" call.
// Exactly one of *CheckResponse or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *CheckResponse.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 *AssetlinksCheckCall) Do(opts ...googleapi.CallOption) (*CheckResponse, 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 := &CheckResponse{
		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": "Determines whether the specified (directional) relationship exists between\nthe specified source and target assets.\n\nThe relation describes the intent of the link between the two assets as\nclaimed by the source asset.  An example for such relationships is the\ndelegation of privileges or permissions.\n\nThis command is most often used by infrastructure systems to check\npreconditions for an action.  For example, a client may want to know if it\nis OK to send a web URL to a particular mobile app instead. The client can\ncheck for the relevant asset link from the website to the mobile app to\ndecide if the operation should be allowed.\n\nA note about security: if you specify a secure asset as the source, such as\nan HTTPS website or an Android app, the API will ensure that any\nstatements used to generate the response have been made in a secure way by\nthe owner of that asset.  Conversely, if the source asset is an insecure\nHTTP website (that is, the URL starts with `http://` instead of\n`https://`), the API cannot verify its statements securely, and it is not\npossible to ensure that the website's statements have not been altered by a\nthird party.  For more information, see the [Digital Asset Links technical\ndesign\nspecification](https://github.com/google/digitalassetlinks/blob/master/well-known/details.md).",
	//   "flatPath": "v1/assetlinks:check",
	//   "httpMethod": "GET",
	//   "id": "digitalassetlinks.assetlinks.check",
	//   "parameterOrder": [],
	//   "parameters": {
	//     "relation": {
	//       "description": "Query string for the relation.\n\nWe identify relations with strings of the format `\u003ckind\u003e/\u003cdetail\u003e`, where\n`\u003ckind\u003e` must be one of a set of pre-defined purpose categories, and\n`\u003cdetail\u003e` is a free-form lowercase alphanumeric string that describes the\nspecific use case of the statement.\n\nRefer to [our API documentation](/digital-asset-links/v1/relation-strings)\nfor the current list of supported relations.\n\nFor a query to match an asset link, both the query's and the asset link's\nrelation strings must match exactly.\n\nExample: A query with relation `delegate_permission/common.handle_all_urls`\nmatches an asset link with relation\n`delegate_permission/common.handle_all_urls`.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "source.androidApp.certificate.sha256Fingerprint": {
	//       "description": "The uppercase SHA-265 fingerprint of the certificate.  From the PEM\n certificate, it can be acquired like this:\n\n    $ keytool -printcert -file $CERTFILE | grep SHA256:\n    SHA256: 14:6D:E9:83:C5:73:06:50:D8:EE:B9:95:2F:34:FC:64:16:A0:83: \\\n        42:E6:1D:BE:A8:8A:04:96:B2:3F:CF:44:E5\n\nor like this:\n\n    $ openssl x509 -in $CERTFILE -noout -fingerprint -sha256\n    SHA256 Fingerprint=14:6D:E9:83:C5:73:06:50:D8:EE:B9:95:2F:34:FC:64: \\\n        16:A0:83:42:E6:1D:BE:A8:8A:04:96:B2:3F:CF:44:E5\n\nIn this example, the contents of this field would be `14:6D:E9:83:C5:73:\n06:50:D8:EE:B9:95:2F:34:FC:64:16:A0:83:42:E6:1D:BE:A8:8A:04:96:B2:3F:CF:\n44:E5`.\n\nIf these tools are not available to you, you can convert the PEM\ncertificate into the DER format, compute the SHA-256 hash of that string\nand represent the result as a hexstring (that is, uppercase hexadecimal\nrepresentations of each octet, separated by colons).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "source.androidApp.packageName": {
	//       "description": "Android App assets are naturally identified by their Java package name.\nFor example, the Google Maps app uses the package name\n`com.google.android.apps.maps`.\nREQUIRED",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "source.web.site": {
	//       "description": "Web assets are identified by a URL that contains only the scheme, hostname\nand port parts.  The format is\n\n    http[s]://\u003chostname\u003e[:\u003cport\u003e]\n\nHostnames must be fully qualified: they must end in a single period\n(\"`.`\").\n\nOnly the schemes \"http\" and \"https\" are currently allowed.\n\nPort numbers are given as a decimal number, and they must be omitted if the\nstandard port numbers are used: 80 for http and 443 for https.\n\nWe call this limited URL the \"site\".  All URLs that share the same scheme,\nhostname and port are considered to be a part of the site and thus belong\nto the web asset.\n\nExample: the asset with the site `https://www.google.com` contains all\nthese URLs:\n\n  *   `https://www.google.com/`\n  *   `https://www.google.com:443/`\n  *   `https://www.google.com/foo`\n  *   `https://www.google.com/foo?bar`\n  *   `https://www.google.com/foo#bar`\n  *   `https://user@password:www.google.com/`\n\nBut it does not contain these URLs:\n\n  *   `http://www.google.com/`       (wrong scheme)\n  *   `https://google.com/`          (hostname does not match)\n  *   `https://www.google.com:444/`  (port does not match)\nREQUIRED",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "target.androidApp.certificate.sha256Fingerprint": {
	//       "description": "The uppercase SHA-265 fingerprint of the certificate.  From the PEM\n certificate, it can be acquired like this:\n\n    $ keytool -printcert -file $CERTFILE | grep SHA256:\n    SHA256: 14:6D:E9:83:C5:73:06:50:D8:EE:B9:95:2F:34:FC:64:16:A0:83: \\\n        42:E6:1D:BE:A8:8A:04:96:B2:3F:CF:44:E5\n\nor like this:\n\n    $ openssl x509 -in $CERTFILE -noout -fingerprint -sha256\n    SHA256 Fingerprint=14:6D:E9:83:C5:73:06:50:D8:EE:B9:95:2F:34:FC:64: \\\n        16:A0:83:42:E6:1D:BE:A8:8A:04:96:B2:3F:CF:44:E5\n\nIn this example, the contents of this field would be `14:6D:E9:83:C5:73:\n06:50:D8:EE:B9:95:2F:34:FC:64:16:A0:83:42:E6:1D:BE:A8:8A:04:96:B2:3F:CF:\n44:E5`.\n\nIf these tools are not available to you, you can convert the PEM\ncertificate into the DER format, compute the SHA-256 hash of that string\nand represent the result as a hexstring (that is, uppercase hexadecimal\nrepresentations of each octet, separated by colons).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "target.androidApp.packageName": {
	//       "description": "Android App assets are naturally identified by their Java package name.\nFor example, the Google Maps app uses the package name\n`com.google.android.apps.maps`.\nREQUIRED",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "target.web.site": {
	//       "description": "Web assets are identified by a URL that contains only the scheme, hostname\nand port parts.  The format is\n\n    http[s]://\u003chostname\u003e[:\u003cport\u003e]\n\nHostnames must be fully qualified: they must end in a single period\n(\"`.`\").\n\nOnly the schemes \"http\" and \"https\" are currently allowed.\n\nPort numbers are given as a decimal number, and they must be omitted if the\nstandard port numbers are used: 80 for http and 443 for https.\n\nWe call this limited URL the \"site\".  All URLs that share the same scheme,\nhostname and port are considered to be a part of the site and thus belong\nto the web asset.\n\nExample: the asset with the site `https://www.google.com` contains all\nthese URLs:\n\n  *   `https://www.google.com/`\n  *   `https://www.google.com:443/`\n  *   `https://www.google.com/foo`\n  *   `https://www.google.com/foo?bar`\n  *   `https://www.google.com/foo#bar`\n  *   `https://user@password:www.google.com/`\n\nBut it does not contain these URLs:\n\n  *   `http://www.google.com/`       (wrong scheme)\n  *   `https://google.com/`          (hostname does not match)\n  *   `https://www.google.com:444/`  (port does not match)\nREQUIRED",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/assetlinks:check",
	//   "response": {
	//     "$ref": "CheckResponse"
	//   }
	// }

}

// method id "digitalassetlinks.statements.list":

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

// List: Retrieves a list of all statements from a given source that
// match the
// specified target and statement string.
//
// The API guarantees that all statements with secure source assets,
// such as
// HTTPS websites or Android apps, have been made in a secure way by the
// owner
// of those assets, as described in the [Digital Asset Links technical
// design
// specification](https://github.com/google/digitalassetlinks/blob
// /master/well-known/details.md).
// Specifically, you should consider that for insecure websites (that
// is,
// where the URL starts with `http://` instead of `https://`), this
// guarantee
// cannot be made.
//
// The `List` command is most useful in cases where the API client wants
// to
// know all the ways in which two assets are related, or enumerate all
// the
// relationships from a particular source asset.  Example: a feature
// that
// helps users navigate to related items.  When a mobile app is running
// on a
// device, the feature would make it easy to navigate to the
// corresponding web
// site or Google+ profile.
func (r *StatementsService) List() *StatementsListCall {
	c := &StatementsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	return c
}

// Relation sets the optional parameter "relation": Use only
// associations that match the specified relation.
//
// See the [`Statement`](#Statement) message for a detailed definition
// of
// relation strings.
//
// For a query to match a statement, one of the following must be
// true:
//
// *    both the query's and the statement's relation strings match
// exactly,
//      or
// *    the query's relation string is empty or missing.
//
// Example: A query with relation
// `delegate_permission/common.handle_all_urls`
// matches an asset link with
// relation
// `delegate_permission/common.handle_all_urls`.
func (c *StatementsListCall) Relation(relation string) *StatementsListCall {
	c.urlParams_.Set("relation", relation)
	return c
}

// SourceAndroidAppCertificateSha256Fingerprint sets the optional
// parameter "source.androidApp.certificate.sha256Fingerprint": The
// uppercase SHA-265 fingerprint of the certificate.  From the PEM
//  certificate, it can be acquired like this:
//
//     $ keytool -printcert -file $CERTFILE | grep SHA256:
//     SHA256: 14:6D:E9:83:C5:73:06:50:D8:EE:B9:95:2F:34:FC:64:16:A0:83:
// \
//         42:E6:1D:BE:A8:8A:04:96:B2:3F:CF:44:E5
//
// or like this:
//
//     $ openssl x509 -in $CERTFILE -noout -fingerprint -sha256
//     SHA256
// Fingerprint=14:6D:E9:83:C5:73:06:50:D8:EE:B9:95:2F:34:FC:64: \
//         16:A0:83:42:E6:1D:BE:A8:8A:04:96:B2:3F:CF:44:E5
//
// In this example, the contents of this field would be
// `14:6D:E9:83:C5:73:
// 06:50:D8:EE:B9:95:2F:34:FC:64:16:A0:83:42:E6:1D:BE
// :A8:8A:04:96:B2:3F:CF:
// 44:E5`.
//
// If these tools are not available to you, you can convert the
// PEM
// certificate into the DER format, compute the SHA-256 hash of that
// string
// and represent the result as a hexstring (that is, uppercase
// hexadecimal
// representations of each octet, separated by colons).
func (c *StatementsListCall) SourceAndroidAppCertificateSha256Fingerprint(sourceAndroidAppCertificateSha256Fingerprint string) *StatementsListCall {
	c.urlParams_.Set("source.androidApp.certificate.sha256Fingerprint", sourceAndroidAppCertificateSha256Fingerprint)
	return c
}

// SourceAndroidAppPackageName sets the optional parameter
// "source.androidApp.packageName": Android App assets are naturally
// identified by their Java package name.
// For example, the Google Maps app uses the package
// name
// `com.google.android.apps.maps`.
// REQUIRED
func (c *StatementsListCall) SourceAndroidAppPackageName(sourceAndroidAppPackageName string) *StatementsListCall {
	c.urlParams_.Set("source.androidApp.packageName", sourceAndroidAppPackageName)
	return c
}

// SourceWebSite sets the optional parameter "source.web.site": Web
// assets are identified by a URL that contains only the scheme,
// hostname
// and port parts.  The format is
//
//     http[s]://<hostname>[:<port>]
//
// Hostnames must be fully qualified: they must end in a single
// period
// (".").
//
// Only the schemes "http" and "https" are currently allowed.
//
// Port numbers are given as a decimal number, and they must be omitted
// if the
// standard port numbers are used: 80 for http and 443 for https.
//
// We call this limited URL the "site".  All URLs that share the same
// scheme,
// hostname and port are considered to be a part of the site and thus
// belong
// to the web asset.
//
// Example: the asset with the site `https://www.google.com` contains
// all
// these URLs:
//
//   *   `https://www.google.com/`
//   *   `https://www.google.com:443/`
//   *   `https://www.google.com/foo`
//   *   `https://www.google.com/foo?bar`
//   *   `https://www.google.com/foo#bar`
//   *   `https://user@password:www.google.com/`
//
// But it does not contain these URLs:
//
//   *   `http://www.google.com/`       (wrong scheme)
//   *   `https://google.com/`          (hostname does not match)
//   *   `https://www.google.com:444/`  (port does not match)
// REQUIRED
func (c *StatementsListCall) SourceWebSite(sourceWebSite string) *StatementsListCall {
	c.urlParams_.Set("source.web.site", sourceWebSite)
	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 *StatementsListCall) Fields(s ...googleapi.Field) *StatementsListCall {
	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 *StatementsListCall) IfNoneMatch(entityTag string) *StatementsListCall {
	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 *StatementsListCall) Context(ctx context.Context) *StatementsListCall {
	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 *StatementsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *StatementsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200317")
	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/statements:list")
	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 "digitalassetlinks.statements.list" call.
// Exactly one of *ListResponse or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *ListResponse.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 *StatementsListCall) Do(opts ...googleapi.CallOption) (*ListResponse, 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 := &ListResponse{
		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": "Retrieves a list of all statements from a given source that match the\nspecified target and statement string.\n\nThe API guarantees that all statements with secure source assets, such as\nHTTPS websites or Android apps, have been made in a secure way by the owner\nof those assets, as described in the [Digital Asset Links technical design\nspecification](https://github.com/google/digitalassetlinks/blob/master/well-known/details.md).\nSpecifically, you should consider that for insecure websites (that is,\nwhere the URL starts with `http://` instead of `https://`), this guarantee\ncannot be made.\n\nThe `List` command is most useful in cases where the API client wants to\nknow all the ways in which two assets are related, or enumerate all the\nrelationships from a particular source asset.  Example: a feature that\nhelps users navigate to related items.  When a mobile app is running on a\ndevice, the feature would make it easy to navigate to the corresponding web\nsite or Google+ profile.",
	//   "flatPath": "v1/statements:list",
	//   "httpMethod": "GET",
	//   "id": "digitalassetlinks.statements.list",
	//   "parameterOrder": [],
	//   "parameters": {
	//     "relation": {
	//       "description": "Use only associations that match the specified relation.\n\nSee the [`Statement`](#Statement) message for a detailed definition of\nrelation strings.\n\nFor a query to match a statement, one of the following must be true:\n\n*    both the query's and the statement's relation strings match exactly,\n     or\n*    the query's relation string is empty or missing.\n\nExample: A query with relation `delegate_permission/common.handle_all_urls`\nmatches an asset link with relation\n`delegate_permission/common.handle_all_urls`.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "source.androidApp.certificate.sha256Fingerprint": {
	//       "description": "The uppercase SHA-265 fingerprint of the certificate.  From the PEM\n certificate, it can be acquired like this:\n\n    $ keytool -printcert -file $CERTFILE | grep SHA256:\n    SHA256: 14:6D:E9:83:C5:73:06:50:D8:EE:B9:95:2F:34:FC:64:16:A0:83: \\\n        42:E6:1D:BE:A8:8A:04:96:B2:3F:CF:44:E5\n\nor like this:\n\n    $ openssl x509 -in $CERTFILE -noout -fingerprint -sha256\n    SHA256 Fingerprint=14:6D:E9:83:C5:73:06:50:D8:EE:B9:95:2F:34:FC:64: \\\n        16:A0:83:42:E6:1D:BE:A8:8A:04:96:B2:3F:CF:44:E5\n\nIn this example, the contents of this field would be `14:6D:E9:83:C5:73:\n06:50:D8:EE:B9:95:2F:34:FC:64:16:A0:83:42:E6:1D:BE:A8:8A:04:96:B2:3F:CF:\n44:E5`.\n\nIf these tools are not available to you, you can convert the PEM\ncertificate into the DER format, compute the SHA-256 hash of that string\nand represent the result as a hexstring (that is, uppercase hexadecimal\nrepresentations of each octet, separated by colons).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "source.androidApp.packageName": {
	//       "description": "Android App assets are naturally identified by their Java package name.\nFor example, the Google Maps app uses the package name\n`com.google.android.apps.maps`.\nREQUIRED",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "source.web.site": {
	//       "description": "Web assets are identified by a URL that contains only the scheme, hostname\nand port parts.  The format is\n\n    http[s]://\u003chostname\u003e[:\u003cport\u003e]\n\nHostnames must be fully qualified: they must end in a single period\n(\"`.`\").\n\nOnly the schemes \"http\" and \"https\" are currently allowed.\n\nPort numbers are given as a decimal number, and they must be omitted if the\nstandard port numbers are used: 80 for http and 443 for https.\n\nWe call this limited URL the \"site\".  All URLs that share the same scheme,\nhostname and port are considered to be a part of the site and thus belong\nto the web asset.\n\nExample: the asset with the site `https://www.google.com` contains all\nthese URLs:\n\n  *   `https://www.google.com/`\n  *   `https://www.google.com:443/`\n  *   `https://www.google.com/foo`\n  *   `https://www.google.com/foo?bar`\n  *   `https://www.google.com/foo#bar`\n  *   `https://user@password:www.google.com/`\n\nBut it does not contain these URLs:\n\n  *   `http://www.google.com/`       (wrong scheme)\n  *   `https://google.com/`          (hostname does not match)\n  *   `https://www.google.com:444/`  (port does not match)\nREQUIRED",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/statements:list",
	//   "response": {
	//     "$ref": "ListResponse"
	//   }
	// }

}
