// 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 trafficdirector provides access to the Traffic Director API.
//
// For product documentation, see: https://www.envoyproxy.io/docs/envoy/latest/configuration/overview/v2_overview#management-server
//
// Creating a client
//
// Usage example:
//
//   import "google.golang.org/api/trafficdirector/v2"
//   ...
//   ctx := context.Background()
//   trafficdirectorService, err := trafficdirector.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:
//
//   trafficdirectorService, err := trafficdirector.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, ...)
//   trafficdirectorService, err := trafficdirector.NewService(ctx, option.WithTokenSource(config.TokenSource(ctx, token)))
//
// See https://godoc.org/google.golang.org/api/option/ for details on options.
package trafficdirector // import "google.golang.org/api/trafficdirector/v2"

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 = "trafficdirector:v2"
const apiName = "trafficdirector"
const apiVersion = "v2"
const basePath = "https://trafficdirector.googleapis.com/"
const mtlsBasePath = "https://trafficdirector.mtls.googleapis.com/"

// OAuth2 scopes used by this API.
const (
	// View and manage your data across Google Cloud Platform services
	CloudPlatformScope = "https://www.googleapis.com/auth/cloud-platform"
)

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

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

	Discovery *DiscoveryService
}

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

func NewDiscoveryService(s *Service) *DiscoveryService {
	rs := &DiscoveryService{s: s}
	return rs
}

type DiscoveryService struct {
	s *Service
}

// Address: Addresses specify either a logical or physical address and
// port, which are used to tell Envoy where to bind/listen, connect to
// upstream and find management servers.
type Address struct {
	Pipe *Pipe `json:"pipe,omitempty"`

	SocketAddress *SocketAddress `json:"socketAddress,omitempty"`

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

// BuildVersion: BuildVersion combines SemVer version of extension with
// free-form build information (i.e. 'alpha', 'private-build') as a set
// of strings.
type BuildVersion struct {
	// Metadata: Free-form build information. Envoy defines several well
	// known keys in the source/common/version/version.h file
	Metadata googleapi.RawMessage `json:"metadata,omitempty"`

	// Version: SemVer version of extension.
	Version *SemanticVersion `json:"version,omitempty"`

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

// ClientConfig: All xds configs for a particular client.
type ClientConfig struct {
	// Node: Node for a particular client.
	Node *Node `json:"node,omitempty"`

	XdsConfig []*PerXdsConfig `json:"xdsConfig,omitempty"`

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

// ClientStatusRequest: Request for client status of clients identified
// by a list of NodeMatchers.
type ClientStatusRequest struct {
	// NodeMatchers: Management server can use these match criteria to
	// identify clients. The match follows OR semantics.
	NodeMatchers []*NodeMatcher `json:"nodeMatchers,omitempty"`

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

type ClientStatusResponse struct {
	// Config: Client configs for the clients specified in the
	// ClientStatusRequest.
	Config []*ClientConfig `json:"config,omitempty"`

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

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

// ClustersConfigDump: Envoy's cluster manager fills this message with
// all currently known clusters. Cluster configuration information can
// be used to recreate an Envoy configuration by populating all clusters
// as static clusters or by returning them in a CDS response.
type ClustersConfigDump struct {
	// DynamicActiveClusters: The dynamically loaded active clusters. These
	// are clusters that are available to service data plane traffic.
	DynamicActiveClusters []*DynamicCluster `json:"dynamicActiveClusters,omitempty"`

	// DynamicWarmingClusters: The dynamically loaded warming clusters.
	// These are clusters that are currently undergoing warming in
	// preparation to service data plane traffic. Note that if attempting to
	// recreate an Envoy configuration from a configuration dump, the
	// warming clusters should generally be discarded.
	DynamicWarmingClusters []*DynamicCluster `json:"dynamicWarmingClusters,omitempty"`

	// StaticClusters: The statically loaded cluster configs.
	StaticClusters []*StaticCluster `json:"staticClusters,omitempty"`

	// VersionInfo: This is the :ref:`version_info ` in the last processed
	// CDS discovery response. If there are only static bootstrap clusters,
	// this field will be "".
	VersionInfo string `json:"versionInfo,omitempty"`

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

// DoubleMatcher: Specifies the way to match a double value.
type DoubleMatcher struct {
	// Exact: If specified, the input double value must be equal to the
	// value specified here.
	Exact float64 `json:"exact,omitempty"`

	// Range: If specified, the input double value must be in the range
	// specified here. Note: The range is using half-open interval semantics
	// [start, end).
	Range *DoubleRange `json:"range,omitempty"`

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

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

// DoubleRange: Specifies the double start and end of the range using
// half-open interval semantics [start, end).
type DoubleRange struct {
	// End: end of the range (exclusive)
	End float64 `json:"end,omitempty"`

	// Start: start of the range (inclusive)
	Start float64 `json:"start,omitempty"`

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

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

// DynamicCluster: Describes a dynamically loaded cluster via the CDS
// API.
type DynamicCluster struct {
	// Cluster: The cluster config.
	Cluster googleapi.RawMessage `json:"cluster,omitempty"`

	// LastUpdated: The timestamp when the Cluster was last updated.
	LastUpdated string `json:"lastUpdated,omitempty"`

	// VersionInfo: This is the per-resource version information. This
	// version is currently taken from the :ref:`version_info ` field at the
	// time that the cluster was loaded. In the future, discrete per-cluster
	// versions may be supported by the API.
	VersionInfo string `json:"versionInfo,omitempty"`

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

// DynamicListener: Describes a dynamically loaded listener via the LDS
// API. [#next-free-field: 6]
type DynamicListener struct {
	// ActiveState: The listener state for any active listener by this name.
	// These are listeners that are available to service data plane traffic.
	ActiveState *DynamicListenerState `json:"activeState,omitempty"`

	// DrainingState: The listener state for any draining listener by this
	// name. These are listeners that are currently undergoing draining in
	// preparation to stop servicing data plane traffic. Note that if
	// attempting to recreate an Envoy configuration from a configuration
	// dump, the draining listeners should generally be discarded.
	DrainingState *DynamicListenerState `json:"drainingState,omitempty"`

	// ErrorState: Set if the last update failed, cleared after the next
	// successful update.
	ErrorState *UpdateFailureState `json:"errorState,omitempty"`

	// Name: The name or unique id of this listener, pulled from the
	// DynamicListenerState config.
	Name string `json:"name,omitempty"`

	// WarmingState: The listener state for any warming listener by this
	// name. These are listeners that are currently undergoing warming in
	// preparation to service data plane traffic. Note that if attempting to
	// recreate an Envoy configuration from a configuration dump, the
	// warming listeners should generally be discarded.
	WarmingState *DynamicListenerState `json:"warmingState,omitempty"`

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

type DynamicListenerState struct {
	// LastUpdated: The timestamp when the Listener was last successfully
	// updated.
	LastUpdated string `json:"lastUpdated,omitempty"`

	// Listener: The listener config.
	Listener googleapi.RawMessage `json:"listener,omitempty"`

	// VersionInfo: This is the per-resource version information. This
	// version is currently taken from the :ref:`version_info ` field at the
	// time that the listener was loaded. In the future, discrete
	// per-listener versions may be supported by the API.
	VersionInfo string `json:"versionInfo,omitempty"`

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

type DynamicRouteConfig struct {
	// LastUpdated: The timestamp when the Route was last updated.
	LastUpdated string `json:"lastUpdated,omitempty"`

	// RouteConfig: The route config.
	RouteConfig googleapi.RawMessage `json:"routeConfig,omitempty"`

	// VersionInfo: This is the per-resource version information. This
	// version is currently taken from the :ref:`version_info ` field at the
	// time that the route configuration was loaded.
	VersionInfo string `json:"versionInfo,omitempty"`

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

type DynamicScopedRouteConfigs struct {
	// LastUpdated: The timestamp when the scoped route config set was last
	// updated.
	LastUpdated string `json:"lastUpdated,omitempty"`

	// Name: The name assigned to the scoped route configurations.
	Name string `json:"name,omitempty"`

	// ScopedRouteConfigs: The scoped route configurations.
	ScopedRouteConfigs []googleapi.RawMessage `json:"scopedRouteConfigs,omitempty"`

	// VersionInfo: This is the per-resource version information. This
	// version is currently taken from the :ref:`version_info ` field at the
	// time that the scoped routes configuration was loaded.
	VersionInfo string `json:"versionInfo,omitempty"`

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

// Extension: Version and identification for an Envoy extension.
// [#next-free-field: 6]
type Extension struct {
	// Category: Category of the extension. Extension category names use
	// reverse DNS notation. For instance "envoy.filters.listener" for
	// Envoy's built-in listener filters or "com.acme.filters.http" for HTTP
	// filters from acme.com vendor. [#comment:
	Category string `json:"category,omitempty"`

	// Disabled: Indicates that the extension is present but was disabled
	// via dynamic configuration.
	Disabled bool `json:"disabled,omitempty"`

	// Name: This is the name of the Envoy filter as specified in the Envoy
	// configuration, e.g. envoy.filters.http.router, com.acme.widget.
	Name string `json:"name,omitempty"`

	// TypeDescriptor: [#not-implemented-hide:] Type descriptor of extension
	// configuration proto. [#comment:
	TypeDescriptor string `json:"typeDescriptor,omitempty"`

	// Version: The version is a property of the extension and maintained
	// independently of other extensions and the Envoy API. This field is
	// not set when extension did not provide version information.
	Version *BuildVersion `json:"version,omitempty"`

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

// GoogleRE2: Google's `RE2 `_ regex engine. The regex string must
// adhere to the documented `syntax `_. The engine is designed to
// complete execution in linear time as well as limit the amount of
// memory used. Envoy supports program size checking via runtime. The
// runtime keys `re2.max_program_size.error_level` and
// `re2.max_program_size.warn_level` can be set to integers as the
// maximum program size or complexity that a compiled regex can have
// before an exception is thrown or a warning is logged, respectively.
// `re2.max_program_size.error_level` defaults to 100, and
// `re2.max_program_size.warn_level` has no default if unset (will not
// check/log a warning). Envoy emits two stats for tracking the program
// size of regexes: the histogram `re2.program_size`, which records the
// program size, and the counter `re2.exceeded_warn_level`, which is
// incremented each time the program size exceeds the warn level
// threshold.
type GoogleRE2 struct {
	// MaxProgramSize: This field controls the RE2 "program size" which is a
	// rough estimate of how complex a compiled regex is to evaluate. A
	// regex that has a program size greater than the configured value will
	// fail to compile. In this case, the configured max program size can be
	// increased or the regex can be simplified. If not specified, the
	// default is 100. This field is deprecated; regexp validation should be
	// performed on the management server instead of being done by each
	// individual client.
	MaxProgramSize int64 `json:"maxProgramSize,omitempty"`

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

type InlineScopedRouteConfigs struct {
	// LastUpdated: The timestamp when the scoped route config set was last
	// updated.
	LastUpdated string `json:"lastUpdated,omitempty"`

	// Name: The name assigned to the scoped route configurations.
	Name string `json:"name,omitempty"`

	// ScopedRouteConfigs: The scoped route configurations.
	ScopedRouteConfigs []googleapi.RawMessage `json:"scopedRouteConfigs,omitempty"`

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

// ListMatcher: Specifies the way to match a list value.
type ListMatcher struct {
	// OneOf: If specified, at least one of the values in the list must
	// match the value specified.
	OneOf *ValueMatcher `json:"oneOf,omitempty"`

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

// ListenersConfigDump: Envoy's listener manager fills this message with
// all currently known listeners. Listener configuration information can
// be used to recreate an Envoy configuration by populating all
// listeners as static listeners or by returning them in a LDS response.
type ListenersConfigDump struct {
	// DynamicListeners: State for any warming, active, or draining
	// listeners.
	DynamicListeners []*DynamicListener `json:"dynamicListeners,omitempty"`

	// StaticListeners: The statically loaded listener configs.
	StaticListeners []*StaticListener `json:"staticListeners,omitempty"`

	// VersionInfo: This is the :ref:`version_info ` in the last processed
	// LDS discovery response. If there are only static bootstrap listeners,
	// this field will be "".
	VersionInfo string `json:"versionInfo,omitempty"`

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

// Locality: Identifies location of where either Envoy runs or where
// upstream hosts run.
type Locality struct {
	// Region: Region this :ref:`zone ` belongs to.
	Region string `json:"region,omitempty"`

	// SubZone: When used for locality of upstream hosts, this field further
	// splits zone into smaller chunks of sub-zones so they can be load
	// balanced independently.
	SubZone string `json:"subZone,omitempty"`

	// Zone: Defines the local service zone where Envoy is running. Though
	// optional, it should be set if discovery service routing is used and
	// the discovery service exposes :ref:`zone data `, either in this
	// message or via :option:`--service-zone`. The meaning of zone is
	// context dependent, e.g. `Availability Zone (AZ) `_ on AWS, `Zone `_
	// on GCP, etc.
	Zone string `json:"zone,omitempty"`

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

// Node: Identifies a specific Envoy instance. The node identifier is
// presented to the management server, which may use this identifier to
// distinguish per Envoy configuration for serving. [#next-free-field:
// 12]
type Node struct {
	// BuildVersion: This is motivated by informing a management server
	// during canary which version of Envoy is being tested in a
	// heterogeneous fleet. This will be set by Envoy in management server
	// RPCs. This field is deprecated in favor of the user_agent_name and
	// user_agent_version values.
	BuildVersion string `json:"buildVersion,omitempty"`

	// ClientFeatures: Client feature support list. These are well known
	// features described in the Envoy API repository for a given major
	// version of an API. Client features use reverse DNS naming scheme, for
	// example `com.acme.feature`. See :ref:`the list of features ` that xDS
	// client may support.
	ClientFeatures []string `json:"clientFeatures,omitempty"`

	// Cluster: Defines the local service cluster name where Envoy is
	// running. Though optional, it should be set if any of the following
	// features are used: :ref:`statsd `, :ref:`health check cluster
	// verification `, :ref:`runtime override directory `, :ref:`user agent
	// addition `, :ref:`HTTP global rate limiting `, :ref:`CDS `, and
	// :ref:`HTTP tracing `, either in this message or via
	// :option:`--service-cluster`.
	Cluster string `json:"cluster,omitempty"`

	// Extensions: List of extensions and their versions supported by the
	// node.
	Extensions []*Extension `json:"extensions,omitempty"`

	// Id: An opaque node identifier for the Envoy node. This also provides
	// the local service node name. It should be set if any of the following
	// features are used: :ref:`statsd `, :ref:`CDS `, and :ref:`HTTP
	// tracing `, either in this message or via :option:`--service-node`.
	Id string `json:"id,omitempty"`

	// ListeningAddresses: Known listening ports on the node as a generic
	// hint to the management server for filtering :ref:`listeners ` to be
	// returned. For example, if there is a listener bound to port 80, the
	// list can optionally contain the SocketAddress `(0.0.0.0,80)`. The
	// field is optional and just a hint.
	ListeningAddresses []*Address `json:"listeningAddresses,omitempty"`

	// Locality: Locality specifying where the Envoy instance is running.
	Locality *Locality `json:"locality,omitempty"`

	// Metadata: Opaque metadata extending the node identifier. Envoy will
	// pass this directly to the management server.
	Metadata googleapi.RawMessage `json:"metadata,omitempty"`

	// UserAgentBuildVersion: Structured version of the entity requesting
	// config.
	UserAgentBuildVersion *BuildVersion `json:"userAgentBuildVersion,omitempty"`

	// UserAgentName: Free-form string that identifies the entity requesting
	// config. E.g. "envoy" or "grpc"
	UserAgentName string `json:"userAgentName,omitempty"`

	// UserAgentVersion: Free-form string that identifies the version of the
	// entity requesting config. E.g. "1.12.2" or "abcd1234", or
	// "SpecialEnvoyBuild"
	UserAgentVersion string `json:"userAgentVersion,omitempty"`

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

// NodeMatcher: Specifies the way to match a Node. The match follows AND
// semantics.
type NodeMatcher struct {
	// NodeId: Specifies match criteria on the node id.
	NodeId *StringMatcher `json:"nodeId,omitempty"`

	// NodeMetadatas: Specifies match criteria on the node metadata.
	NodeMetadatas []*StructMatcher `json:"nodeMetadatas,omitempty"`

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

// NullMatch: NullMatch is an empty message to specify a null value.
type NullMatch struct {
}

// PathSegment: Specifies the segment in a path to retrieve value from
// Struct.
type PathSegment struct {
	// Key: If specified, use the key to retrieve the value in a Struct.
	Key string `json:"key,omitempty"`

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

// PerXdsConfig: Detailed config (per xDS) with status.
// [#next-free-field: 6]
type PerXdsConfig struct {
	ClusterConfig *ClustersConfigDump `json:"clusterConfig,omitempty"`

	ListenerConfig *ListenersConfigDump `json:"listenerConfig,omitempty"`

	RouteConfig *RoutesConfigDump `json:"routeConfig,omitempty"`

	ScopedRouteConfig *ScopedRoutesConfigDump `json:"scopedRouteConfig,omitempty"`

	// Possible values:
	//   "UNKNOWN" - Status info is not available/unknown.
	//   "SYNCED" - Management server has sent the config to client and
	// received ACK.
	//   "NOT_SENT" - Config is not sent.
	//   "STALE" - Management server has sent the config to client but
	// hasn’t received ACK/NACK.
	//   "ERROR" - Management server has sent the config to client but
	// received NACK.
	Status string `json:"status,omitempty"`

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

type Pipe struct {
	// Mode: The mode for the Pipe. Not applicable for abstract sockets.
	Mode int64 `json:"mode,omitempty"`

	// Path: Unix Domain Socket path. On Linux, paths starting with '@' will
	// use the abstract namespace. The starting '@' is replaced by a null
	// byte by Envoy. Paths starting with '@' will result in an error in
	// environments other than Linux.
	Path string `json:"path,omitempty"`

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

// RegexMatcher: A regex matcher designed for safety when used with
// untrusted input.
type RegexMatcher struct {
	// GoogleRe2: Google's RE2 regex engine.
	GoogleRe2 *GoogleRE2 `json:"googleRe2,omitempty"`

	// Regex: The regex match string. The string must be supported by the
	// configured engine.
	Regex string `json:"regex,omitempty"`

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

// RoutesConfigDump: Envoy's RDS implementation fills this message with
// all currently loaded routes, as described by their RouteConfiguration
// objects. Static routes that are either defined in the bootstrap
// configuration or defined inline while configuring listeners are
// separated from those configured dynamically via RDS. Route
// configuration information can be used to recreate an Envoy
// configuration by populating all routes as static routes or by
// returning them in RDS responses.
type RoutesConfigDump struct {
	// DynamicRouteConfigs: The dynamically loaded route configs.
	DynamicRouteConfigs []*DynamicRouteConfig `json:"dynamicRouteConfigs,omitempty"`

	// StaticRouteConfigs: The statically loaded route configs.
	StaticRouteConfigs []*StaticRouteConfig `json:"staticRouteConfigs,omitempty"`

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

// ScopedRoutesConfigDump: Envoy's scoped RDS implementation fills this
// message with all currently loaded route configuration scopes (defined
// via ScopedRouteConfigurationsSet protos). This message lists both the
// scopes defined inline with the higher order object (i.e., the
// HttpConnectionManager) and the dynamically obtained scopes via the
// SRDS API.
type ScopedRoutesConfigDump struct {
	// DynamicScopedRouteConfigs: The dynamically loaded scoped route
	// configs.
	DynamicScopedRouteConfigs []*DynamicScopedRouteConfigs `json:"dynamicScopedRouteConfigs,omitempty"`

	// InlineScopedRouteConfigs: The statically loaded scoped route configs.
	InlineScopedRouteConfigs []*InlineScopedRouteConfigs `json:"inlineScopedRouteConfigs,omitempty"`

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

// SemanticVersion: Envoy uses SemVer (https://semver.org/). Major/minor
// versions indicate expected behaviors and APIs, the patch version
// field is used only for security fixes and can be generally ignored.
type SemanticVersion struct {
	MajorNumber int64 `json:"majorNumber,omitempty"`

	MinorNumber int64 `json:"minorNumber,omitempty"`

	Patch int64 `json:"patch,omitempty"`

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

// SocketAddress: [#next-free-field: 7]
type SocketAddress struct {
	// Address: The address for this socket. :ref:`Listeners ` will bind to
	// the address. An empty address is not allowed. Specify ``0.0.0.0`` or
	// ``::`` to bind to any address. [#comment:TODO(zuercher) reinstate
	// when implemented: It is possible to distinguish a Listener address
	// via the prefix/suffix matching in :ref:`FilterChainMatch `.] When
	// used within an upstream :ref:`BindConfig `, the address controls the
	// source address of outbound connections. For :ref:`clusters `, the
	// cluster type determines whether the address must be an IP (*STATIC*
	// or *EDS* clusters) or a hostname resolved by DNS (*STRICT_DNS* or
	// *LOGICAL_DNS* clusters). Address resolution can be customized via
	// :ref:`resolver_name `.
	Address string `json:"address,omitempty"`

	// Ipv4Compat: When binding to an IPv6 address above, this enables `IPv4
	// compatibility `_. Binding to ``::`` will allow both IPv4 and IPv6
	// connections, with peer IPv4 addresses mapped into IPv6 space as
	// ``::FFFF:``.
	Ipv4Compat bool `json:"ipv4Compat,omitempty"`

	// NamedPort: This is only valid if :ref:`resolver_name ` is specified
	// below and the named resolver is capable of named port resolution.
	NamedPort string `json:"namedPort,omitempty"`

	PortValue int64 `json:"portValue,omitempty"`

	// Possible values:
	//   "TCP"
	//   "UDP"
	Protocol string `json:"protocol,omitempty"`

	// ResolverName: The name of the custom resolver. This must have been
	// registered with Envoy. If this is empty, a context dependent default
	// applies. If the address is a concrete IP address, no resolution will
	// occur. If address is a hostname this should be set for resolution
	// other than DNS. Specifying a custom resolver with *STRICT_DNS* or
	// *LOGICAL_DNS* will generate an error at runtime.
	ResolverName string `json:"resolverName,omitempty"`

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

// StaticCluster: Describes a statically loaded cluster.
type StaticCluster struct {
	// Cluster: The cluster config.
	Cluster googleapi.RawMessage `json:"cluster,omitempty"`

	// LastUpdated: The timestamp when the Cluster was last updated.
	LastUpdated string `json:"lastUpdated,omitempty"`

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

// StaticListener: Describes a statically loaded listener.
type StaticListener struct {
	// LastUpdated: The timestamp when the Listener was last successfully
	// updated.
	LastUpdated string `json:"lastUpdated,omitempty"`

	// Listener: The listener config.
	Listener googleapi.RawMessage `json:"listener,omitempty"`

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

type StaticRouteConfig struct {
	// LastUpdated: The timestamp when the Route was last updated.
	LastUpdated string `json:"lastUpdated,omitempty"`

	// RouteConfig: The route config.
	RouteConfig googleapi.RawMessage `json:"routeConfig,omitempty"`

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

// StringMatcher: Specifies the way to match a string.
// [#next-free-field: 7]
type StringMatcher struct {
	// Exact: The input string must match exactly the string specified here.
	// Examples: * *abc* only matches the value *abc*.
	Exact string `json:"exact,omitempty"`

	// IgnoreCase: If true, indicates the exact/prefix/suffix matching
	// should be case insensitive. This has no effect for the safe_regex
	// match. For example, the matcher *data* will match both input string
	// *Data* and *data* if set to true.
	IgnoreCase bool `json:"ignoreCase,omitempty"`

	// Prefix: The input string must have the prefix specified here. Note:
	// empty prefix is not allowed, please use regex instead. Examples: *
	// *abc* matches the value *abc.xyz*
	Prefix string `json:"prefix,omitempty"`

	// Regex: The input string must match the regular expression specified
	// here. The regex grammar is defined `here `_. Examples: * The regex
	// ``\d{3}`` matches the value *123* * The regex ``\d{3}`` does not
	// match the value *1234* * The regex ``\d{3}`` does not match the value
	// *123.456* .. attention:: This field has been deprecated in favor of
	// `safe_regex` as it is not safe for use with untrusted input in all
	// cases.
	Regex string `json:"regex,omitempty"`

	// SafeRegex: The input string must match the regular expression
	// specified here.
	SafeRegex *RegexMatcher `json:"safeRegex,omitempty"`

	// Suffix: The input string must have the suffix specified here. Note:
	// empty prefix is not allowed, please use regex instead. Examples: *
	// *abc* matches the value *xyz.abc*
	Suffix string `json:"suffix,omitempty"`

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

// StructMatcher: StructMatcher provides a general interface to check if
// a given value is matched in google.protobuf.Struct. It uses `path` to
// retrieve the value from the struct and then check if it's matched to
// the specified value. For example, for the following Struct: ..
// code-block:: yaml fields: a: struct_value: fields: b: struct_value:
// fields: c: string_value: pro t: list_value: values: - string_value: m
// - string_value: n The following MetadataMatcher is matched as the
// path [a, b, c] will retrieve a string value "pro" from the Metadata
// which is matched to the specified prefix match. .. code-block:: yaml
// path: - key: a - key: b - key: c value: string_match: prefix: pr The
// following StructMatcher is matched as the code will match one of the
// string values in the list at the path [a, t]. .. code-block:: yaml
// path: - key: a - key: t value: list_match: one_of: string_match:
// exact: m An example use of StructMatcher is to match metadata in
// envoy.v*.core.Node.
type StructMatcher struct {
	// Path: The path to retrieve the Value from the Struct.
	Path []*PathSegment `json:"path,omitempty"`

	// Value: The StructMatcher is matched if the value retrieved by path is
	// matched to this value.
	Value *ValueMatcher `json:"value,omitempty"`

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

type UpdateFailureState struct {
	// Details: Details about the last failed update attempt.
	Details string `json:"details,omitempty"`

	// FailedConfiguration: What the component configuration would have been
	// if the update had succeeded.
	FailedConfiguration googleapi.RawMessage `json:"failedConfiguration,omitempty"`

	// LastUpdateAttempt: Time of the latest failed update attempt.
	LastUpdateAttempt string `json:"lastUpdateAttempt,omitempty"`

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

// ValueMatcher: Specifies the way to match a ProtobufWkt::Value.
// Primitive values and ListValue are supported. StructValue is not
// supported and is always not matched. [#next-free-field: 7]
type ValueMatcher struct {
	// BoolMatch: If specified, a match occurs if and only if the target
	// value is a bool value and is equal to this field.
	BoolMatch bool `json:"boolMatch,omitempty"`

	// DoubleMatch: If specified, a match occurs if and only if the target
	// value is a double value and is matched to this field.
	DoubleMatch *DoubleMatcher `json:"doubleMatch,omitempty"`

	// ListMatch: If specified, a match occurs if and only if the target
	// value is a list value and is matched to this field.
	ListMatch *ListMatcher `json:"listMatch,omitempty"`

	// NullMatch: If specified, a match occurs if and only if the target
	// value is a NullValue.
	NullMatch *NullMatch `json:"nullMatch,omitempty"`

	// PresentMatch: If specified, value match will be performed based on
	// whether the path is referring to a valid primitive value in the
	// metadata. If the path is referring to a non-primitive value, the
	// result is always not matched.
	PresentMatch bool `json:"presentMatch,omitempty"`

	// StringMatch: If specified, a match occurs if and only if the target
	// value is a string value and is matched to this field.
	StringMatch *StringMatcher `json:"stringMatch,omitempty"`

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

// method id "trafficdirector.discovery.client_status":

type DiscoveryClientStatusCall struct {
	s                   *Service
	clientstatusrequest *ClientStatusRequest
	urlParams_          gensupport.URLParams
	ctx_                context.Context
	header_             http.Header
}

// ClientStatus:
func (r *DiscoveryService) ClientStatus(clientstatusrequest *ClientStatusRequest) *DiscoveryClientStatusCall {
	c := &DiscoveryClientStatusCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.clientstatusrequest = clientstatusrequest
	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 *DiscoveryClientStatusCall) Fields(s ...googleapi.Field) *DiscoveryClientStatusCall {
	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 *DiscoveryClientStatusCall) Context(ctx context.Context) *DiscoveryClientStatusCall {
	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 *DiscoveryClientStatusCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *DiscoveryClientStatusCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20201002")
	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.clientstatusrequest)
	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, "v2/discovery:client_status")
	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 "trafficdirector.discovery.client_status" call.
// Exactly one of *ClientStatusResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *ClientStatusResponse.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 *DiscoveryClientStatusCall) Do(opts ...googleapi.CallOption) (*ClientStatusResponse, 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 := &ClientStatusResponse{
		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": "",
	//   "flatPath": "v2/discovery:client_status",
	//   "httpMethod": "POST",
	//   "id": "trafficdirector.discovery.client_status",
	//   "parameterOrder": [],
	//   "parameters": {},
	//   "path": "v2/discovery:client_status",
	//   "request": {
	//     "$ref": "ClientStatusRequest"
	//   },
	//   "response": {
	//     "$ref": "ClientStatusResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}
