// Copyright YEAR 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 wrapnewlines provides access to the Example API.
//
// Creating a client
//
// Usage example:
//
//   import "google.golang.org/api/wrapnewlines/v1"
//   ...
//   ctx := context.Background()
//   wrapnewlinesService, err := wrapnewlines.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:
//
//   wrapnewlinesService, err := wrapnewlines.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, ...)
//   wrapnewlinesService, err := wrapnewlines.NewService(ctx, option.WithTokenSource(config.TokenSource(ctx, token)))
//
// See https://godoc.org/google.golang.org/api/option/ for details on options.
package wrapnewlines // import "google.golang.org/api/wrapnewlines/v1"

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

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

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

const apiId = "wrapnewlines:v1"
const apiName = "wrapnewlines"
const apiVersion = "v1"
const basePath = "https://www.googleapis.com/discovery/v1/apis"

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

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

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

// Thing: don't care
type Thing struct {
	// BoolEmptyDefaultA:
	// Nonempty default: no
	// Unfortunate default: no
	BoolEmptyDefaultA bool `json:"bool_empty_default_a,omitempty"`

	// BoolEmptyDefaultB:
	// Nonempty default: no
	// Unfortunate default: no
	BoolEmptyDefaultB bool `json:"bool_empty_default_b,omitempty"`

	// BoolNonemptyDefault:
	// Nonempty default: yes
	// Unfortunate default: yes
	//
	// Default: true
	BoolNonemptyDefault *bool `json:"bool_nonempty_default,omitempty"`

	// NumericEmptyDefaultA:
	// Nonempty default: no
	// Unfortunate default: no
	NumericEmptyDefaultA int64 `json:"numeric_empty_default_a,omitempty,string"`

	// NumericEmptyDefaultB:
	// Nonempty default: no
	// Unfortunate default: no
	NumericEmptyDefaultB int64 `json:"numeric_empty_default_b,omitempty,string"`

	// NumericEmptyDefaultC:
	// Nonempty default: no
	// Unfortunate default: no
	NumericEmptyDefaultC int64 `json:"numeric_empty_default_c,omitempty,string"`

	// NumericEmptyDefaultD:
	// Nonempty default: no
	// Unfortunate default: no
	NumericEmptyDefaultD float64 `json:"numeric_empty_default_d,omitempty"`

	// NumericEmptyDefaultE:
	// Nonempty default: no
	// Unfortunate default: no
	NumericEmptyDefaultE float64 `json:"numeric_empty_default_e,omitempty"`

	// NumericNonemptyDefaultA:
	// Nonempty default: yes
	// Unfortunate default: yes
	// string encoded, so will not be represented as pointer.
	//
	// Default: 1
	NumericNonemptyDefaultA *int64 `json:"numeric_nonempty_default_a,omitempty,string"`

	// NumericNonemptyDefaultB:
	// Nonempty default: yes
	// Unfortunate default: yes
	//
	// Default: 0.001
	NumericNonemptyDefaultB *float64 `json:"numeric_nonempty_default_b,omitempty"`

	// StringEmptyDefaultDoesntAcceptEmpty:
	// Nonempty default: no
	// Accepts empty value: no
	// Unfortunate default: no
	StringEmptyDefaultDoesntAcceptEmpty string `json:"string_empty_default_doesnt_accept_empty,omitempty"`

	// StringEmptyDefaultEnumAcceptsEmpty:
	// Nonempty default: no
	// Accepts empty value: yes (enum)
	// Unfortunate default: no
	//
	// Possible values:
	//   "" (default)
	//   "value"
	StringEmptyDefaultEnumAcceptsEmpty string `json:"string_empty_default_enum_accepts_empty,omitempty"`

	// StringEmptyDefaultEnumDoesntAcceptEmpty:
	// Nonempty default: no
	// Accepts empty value: no (enum)
	// Unfortunate default: no
	//
	// Possible values:
	//   "value"
	StringEmptyDefaultEnumDoesntAcceptEmpty string `json:"string_empty_default_enum_doesnt_accept_empty,omitempty"`

	// StringEmptyDefaultPatternAcceptsEmpty:
	// Nonempty default: no
	// Accepts empty value: yes (pattern)
	// Unfortunate default: no
	StringEmptyDefaultPatternAcceptsEmpty string `json:"string_empty_default_pattern_accepts_empty,omitempty"`

	// StringEmptyDefaultPatternDoesntAcceptEmpty:
	// Nonempty default: no
	// Accepts empty value: no (pattern)
	// Unfortunate default: no
	StringEmptyDefaultPatternDoesntAcceptEmpty string `json:"string_empty_default_pattern_doesnt_accept_empty,omitempty"`

	// StringNonemptyDefaultDoesntAcceptEmpty:
	// Nonempty default: yes
	// Accepts empty value: no
	// Unfortunate default: no
	StringNonemptyDefaultDoesntAcceptEmpty string `json:"string_nonempty_default_doesnt_accept_empty,omitempty"`

	// StringNonemptyDefaultEnumAcceptsEmpty:
	// Nonempty default: yes
	// Accepts empty value: yes (enum)
	// Unfortunate default: yes
	//
	// Possible values:
	//   ""
	//   "nonempty" (default)
	//   "aaa"
	StringNonemptyDefaultEnumAcceptsEmpty *string `json:"string_nonempty_default_enum_accepts_empty,omitempty"`

	// StringNonemptyDefaultEnumDoesntAcceptEmpty:
	// Nonempty default: yes
	// Accepts empty value: no (enum)
	// Unfortunate default: no
	//
	// Possible values:
	//   "nonempty" (default)
	//   "aaa"
	StringNonemptyDefaultEnumDoesntAcceptEmpty string `json:"string_nonempty_default_enum_doesnt_accept_empty,omitempty"`

	// StringNonemptyDefaultPatternAcceptsEmpty:
	// Nonempty default: yes
	// Accepts empty value: yes (pattern)
	// Unfortunate default: yes
	//
	// Default: nonempty
	StringNonemptyDefaultPatternAcceptsEmpty *string `json:"string_nonempty_default_pattern_accepts_empty,omitempty"`

	// StringNonemptyDefaultPatternDoesntAcceptEmpty:
	// Nonempty default: yes
	// Accepts empty value: no (pattern)
	// Unfortunate default: no
	StringNonemptyDefaultPatternDoesntAcceptEmpty string `json:"string_nonempty_default_pattern_doesnt_accept_empty,omitempty"`

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

func (s *Thing) UnmarshalJSON(data []byte) error {
	type NoMethod Thing
	var s1 struct {
		NumericEmptyDefaultD    gensupport.JSONFloat64  `json:"numeric_empty_default_d"`
		NumericEmptyDefaultE    gensupport.JSONFloat64  `json:"numeric_empty_default_e"`
		NumericNonemptyDefaultB *gensupport.JSONFloat64 `json:"numeric_nonempty_default_b"`
		*NoMethod
	}
	s1.NoMethod = (*NoMethod)(s)
	if err := json.Unmarshal(data, &s1); err != nil {
		return err
	}
	s.NumericEmptyDefaultD = float64(s1.NumericEmptyDefaultD)
	s.NumericEmptyDefaultE = float64(s1.NumericEmptyDefaultE)
	if s1.NumericNonemptyDefaultB != nil {
		s.NumericNonemptyDefaultB = (*float64)(s1.NumericNonemptyDefaultB)
	}
	return nil
}
