// Copyright 2020 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

//go:build goexperiment.jsonv2

package json

import (
	"bytes"
	"encoding"
	"io"
	"reflect"
	"sync"
	"time"

	"encoding/json/internal"
	"encoding/json/internal/jsonflags"
	"encoding/json/internal/jsonopts"
	"encoding/json/jsontext"
)

// Reference encoding and time packages to assist pkgsite
// in being able to hotlink references to those packages.
var (
	_ encoding.TextMarshaler
	_ encoding.TextAppender
	_ encoding.TextUnmarshaler
	_ time.Time
	_ time.Duration
)

// export exposes internal functionality of the "jsontext" package.
var export = jsontext.Internal.Export(&internal.AllowInternalUse)

// Marshal serializes a Go value as a []byte according to the provided
// marshal and encode options (while ignoring unmarshal or decode options).
// It does not terminate the output with a newline.
//
// Type-specific marshal functions and methods take precedence
// over the default representation of a value.
// Functions or methods that operate on *T are only called when encoding
// a value of type T (by taking its address) or a non-nil value of *T.
// Marshal ensures that a value is always addressable
// (by boxing it on the heap if necessary) so that
// these functions and methods can be consistently called. For performance,
// it is recommended that Marshal be passed a non-nil pointer to the value.
//
// The input value is encoded as JSON according the following rules:
//
//   - If any type-specific functions in a [WithMarshalers] option match
//     the value type, then those functions are called to encode the value.
//     If all applicable functions return [errors.ErrUnsupported],
//     then the value is encoded according to subsequent rules.
//
//   - If the value type implements [MarshalerTo],
//     then the MarshalJSONTo method is called to encode the value.
//     If the method returns [errors.ErrUnsupported],
//     then the input is encoded according to subsequent rules.
//
//   - If the value type implements [Marshaler],
//     then the MarshalJSON method is called to encode the value.
//
//   - If the value type implements [encoding.TextAppender],
//     then the AppendText method is called to encode the value and
//     subsequently encode its result as a JSON string.
//
//   - If the value type implements [encoding.TextMarshaler],
//     then the MarshalText method is called to encode the value and
//     subsequently encode its result as a JSON string.
//
//   - Otherwise, the value is encoded according to the value's type
//     as described in detail below.
//
// Most Go types have a default JSON representation.
// Certain types support specialized formatting according to
// a format flag optionally specified in the Go struct tag
// for the struct field that contains the current value
// (see the “JSON Representation of Go structs” section for more details).
//
// The representation of each type is as follows:
//
//   - A Go boolean is encoded as a JSON boolean (e.g., true or false).
//     It does not support any custom format flags.
//
//   - A Go string is encoded as a JSON string.
//     It does not support any custom format flags.
//
//   - A Go []byte or [N]byte is encoded as a JSON string containing
//     the binary value encoded using RFC 4648.
//     If the format is "base64" or unspecified, then this uses RFC 4648, section 4.
//     If the format is "base64url", then this uses RFC 4648, section 5.
//     If the format is "base32", then this uses RFC 4648, section 6.
//     If the format is "base32hex", then this uses RFC 4648, section 7.
//     If the format is "base16" or "hex", then this uses RFC 4648, section 8.
//     If the format is "array", then the bytes value is encoded as a JSON array
//     where each byte is recursively JSON-encoded as each JSON array element.
//
//   - A Go integer is encoded as a JSON number without fractions or exponents.
//     If [StringifyNumbers] is specified or encoding a JSON object name,
//     then the JSON number is encoded within a JSON string.
//     It does not support any custom format flags.
//
//   - A Go float is encoded as a JSON number.
//     If [StringifyNumbers] is specified or encoding a JSON object name,
//     then the JSON number is encoded within a JSON string.
//     If the format is "nonfinite", then NaN, +Inf, and -Inf are encoded as
//     the JSON strings "NaN", "Infinity", and "-Infinity", respectively.
//     Otherwise, the presence of non-finite numbers results in a [SemanticError].
//
//   - A Go map is encoded as a JSON object, where each Go map key and value
//     is recursively encoded as a name and value pair in the JSON object.
//     The Go map key must encode as a JSON string, otherwise this results
//     in a [SemanticError]. The Go map is traversed in a non-deterministic order.
//     For deterministic encoding, consider using the [Deterministic] option.
//     If the format is "emitnull", then a nil map is encoded as a JSON null.
//     If the format is "emitempty", then a nil map is encoded as an empty JSON object,
//     regardless of whether [FormatNilMapAsNull] is specified.
//     Otherwise by default, a nil map is encoded as an empty JSON object.
//
//   - A Go struct is encoded as a JSON object.
//     See the “JSON Representation of Go structs” section
//     in the package-level documentation for more details.
//
//   - A Go slice is encoded as a JSON array, where each Go slice element
//     is recursively JSON-encoded as the elements of the JSON array.
//     If the format is "emitnull", then a nil slice is encoded as a JSON null.
//     If the format is "emitempty", then a nil slice is encoded as an empty JSON array,
//     regardless of whether [FormatNilSliceAsNull] is specified.
//     Otherwise by default, a nil slice is encoded as an empty JSON array.
//
//   - A Go array is encoded as a JSON array, where each Go array element
//     is recursively JSON-encoded as the elements of the JSON array.
//     The JSON array length is always identical to the Go array length.
//     It does not support any custom format flags.
//
//   - A Go pointer is encoded as a JSON null if nil, otherwise it is
//     the recursively JSON-encoded representation of the underlying value.
//     Format flags are forwarded to the encoding of the underlying value.
//
//   - A Go interface is encoded as a JSON null if nil, otherwise it is
//     the recursively JSON-encoded representation of the underlying value.
//     It does not support any custom format flags.
//
//   - A Go [time.Time] is encoded as a JSON string containing the timestamp
//     formatted in RFC 3339 with nanosecond precision.
//     If the format matches one of the format constants declared
//     in the time package (e.g., RFC1123), then that format is used.
//     If the format is "unix", "unixmilli", "unixmicro", or "unixnano",
//     then the timestamp is encoded as a possibly fractional JSON number
//     of the number of seconds (or milliseconds, microseconds, or nanoseconds)
//     since the Unix epoch, which is January 1st, 1970 at 00:00:00 UTC.
//     To avoid a fractional component, round the timestamp to the relevant unit.
//     Otherwise, the format is used as-is with [time.Time.Format] if non-empty.
//
//   - A Go [time.Duration] currently has no default representation and
//     requires an explicit format to be specified.
//     If the format is "sec", "milli", "micro", or "nano",
//     then the duration is encoded as a possibly fractional JSON number
//     of the number of seconds (or milliseconds, microseconds, or nanoseconds).
//     To avoid a fractional component, round the duration to the relevant unit.
//     If the format is "units", it is encoded as a JSON string formatted using
//     [time.Duration.String] (e.g., "1h30m" for 1 hour 30 minutes).
//     If the format is "iso8601", it is encoded as a JSON string using the
//     ISO 8601 standard for durations (e.g., "PT1H30M" for 1 hour 30 minutes)
//     using only accurate units of hours, minutes, and seconds.
//
//   - All other Go types (e.g., complex numbers, channels, and functions)
//     have no default representation and result in a [SemanticError].
//
// JSON cannot represent cyclic data structures and Marshal does not handle them.
// Passing cyclic structures will result in an error.
func Marshal(in any, opts ...Options) (out []byte, err error) {
	enc := export.GetBufferedEncoder(opts...)
	defer export.PutBufferedEncoder(enc)
	xe := export.Encoder(enc)
	xe.Flags.Set(jsonflags.OmitTopLevelNewline | 1)
	err = marshalEncode(enc, in, &xe.Struct)
	if err != nil && xe.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) {
		return nil, internal.TransformMarshalError(in, err)
	}
	return bytes.Clone(xe.Buf), err
}

// MarshalWrite serializes a Go value into an [io.Writer] according to the provided
// marshal and encode options (while ignoring unmarshal or decode options).
// It does not terminate the output with a newline.
// See [Marshal] for details about the conversion of a Go value into JSON.
func MarshalWrite(out io.Writer, in any, opts ...Options) (err error) {
	enc := export.GetStreamingEncoder(out, opts...)
	defer export.PutStreamingEncoder(enc)
	xe := export.Encoder(enc)
	xe.Flags.Set(jsonflags.OmitTopLevelNewline | 1)
	err = marshalEncode(enc, in, &xe.Struct)
	if err != nil && xe.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) {
		return internal.TransformMarshalError(in, err)
	}
	return err
}

// MarshalEncode serializes a Go value into an [jsontext.Encoder] according to
// the provided marshal options (while ignoring unmarshal, encode, or decode options).
// Any marshal-relevant options already specified on the [jsontext.Encoder]
// take lower precedence than the set of options provided by the caller.
// Unlike [Marshal] and [MarshalWrite], encode options are ignored because
// they must have already been specified on the provided [jsontext.Encoder].
//
// See [Marshal] for details about the conversion of a Go value into JSON.
func MarshalEncode(out *jsontext.Encoder, in any, opts ...Options) (err error) {
	xe := export.Encoder(out)
	if len(opts) > 0 {
		optsOriginal := xe.Struct
		defer func() { xe.Struct = optsOriginal }()
		xe.Struct.JoinWithoutCoderOptions(opts...)
	}
	err = marshalEncode(out, in, &xe.Struct)
	if err != nil && xe.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) {
		return internal.TransformMarshalError(in, err)
	}
	return err
}

func marshalEncode(out *jsontext.Encoder, in any, mo *jsonopts.Struct) (err error) {
	v := reflect.ValueOf(in)
	if !v.IsValid() || (v.Kind() == reflect.Pointer && v.IsNil()) {
		return out.WriteToken(jsontext.Null)
	}
	// Shallow copy non-pointer values to obtain an addressable value.
	// It is beneficial to performance to always pass pointers to avoid this.
	forceAddr := v.Kind() != reflect.Pointer
	if forceAddr {
		v2 := reflect.New(v.Type())
		v2.Elem().Set(v)
		v = v2
	}
	va := addressableValue{v.Elem(), forceAddr} // dereferenced pointer is always addressable
	t := va.Type()

	// Lookup and call the marshal function for this type.
	marshal := lookupArshaler(t).marshal
	if mo.Marshalers != nil {
		marshal, _ = mo.Marshalers.(*Marshalers).lookup(marshal, t)
	}
	if err := marshal(out, va, mo); err != nil {
		if !mo.Flags.Get(jsonflags.AllowDuplicateNames) {
			export.Encoder(out).Tokens.InvalidateDisabledNamespaces()
		}
		return err
	}
	return nil
}

// Unmarshal decodes a []byte input into a Go value according to the provided
// unmarshal and decode options (while ignoring marshal or encode options).
// The input must be a single JSON value with optional whitespace interspersed.
// The output must be a non-nil pointer.
//
// Type-specific unmarshal functions and methods take precedence
// over the default representation of a value.
// Functions or methods that operate on *T are only called when decoding
// a value of type T (by taking its address) or a non-nil value of *T.
// Unmarshal ensures that a value is always addressable
// (by boxing it on the heap if necessary) so that
// these functions and methods can be consistently called.
//
// The input is decoded into the output according the following rules:
//
//   - If any type-specific functions in a [WithUnmarshalers] option match
//     the value type, then those functions are called to decode the JSON
//     value. If all applicable functions return [errors.ErrUnsupported],
//     then the input is decoded according to subsequent rules.
//
//   - If the value type implements [UnmarshalerFrom],
//     then the UnmarshalJSONFrom method is called to decode the JSON value.
//     If the method returns [errors.ErrUnsupported],
//     then the input is decoded according to subsequent rules.
//
//   - If the value type implements [Unmarshaler],
//     then the UnmarshalJSON method is called to decode the JSON value.
//
//   - If the value type implements [encoding.TextUnmarshaler],
//     then the input is decoded as a JSON string and
//     the UnmarshalText method is called with the decoded string value.
//     This fails with a [SemanticError] if the input is not a JSON string.
//
//   - Otherwise, the JSON value is decoded according to the value's type
//     as described in detail below.
//
// Most Go types have a default JSON representation.
// Certain types support specialized formatting according to
// a format flag optionally specified in the Go struct tag
// for the struct field that contains the current value
// (see the “JSON Representation of Go structs” section for more details).
// A JSON null may be decoded into every supported Go value where
// it is equivalent to storing the zero value of the Go value.
// If the input JSON kind is not handled by the current Go value type,
// then this fails with a [SemanticError]. Unless otherwise specified,
// the decoded value replaces any pre-existing value.
//
// The representation of each type is as follows:
//
//   - A Go boolean is decoded from a JSON boolean (e.g., true or false).
//     It does not support any custom format flags.
//
//   - A Go string is decoded from a JSON string.
//     It does not support any custom format flags.
//
//   - A Go []byte or [N]byte is decoded from a JSON string
//     containing the binary value encoded using RFC 4648.
//     If the format is "base64" or unspecified, then this uses RFC 4648, section 4.
//     If the format is "base64url", then this uses RFC 4648, section 5.
//     If the format is "base32", then this uses RFC 4648, section 6.
//     If the format is "base32hex", then this uses RFC 4648, section 7.
//     If the format is "base16" or "hex", then this uses RFC 4648, section 8.
//     If the format is "array", then the Go slice or array is decoded from a
//     JSON array where each JSON element is recursively decoded for each byte.
//     When decoding into a non-nil []byte, the slice length is reset to zero
//     and the decoded input is appended to it.
//     When decoding into a [N]byte, the input must decode to exactly N bytes,
//     otherwise it fails with a [SemanticError].
//
//   - A Go integer is decoded from a JSON number.
//     It must be decoded from a JSON string containing a JSON number
//     if [StringifyNumbers] is specified or decoding a JSON object name.
//     It fails with a [SemanticError] if the JSON number
//     has a fractional or exponent component.
//     It also fails if it overflows the representation of the Go integer type.
//     It does not support any custom format flags.
//
//   - A Go float is decoded from a JSON number.
//     It must be decoded from a JSON string containing a JSON number
//     if [StringifyNumbers] is specified or decoding a JSON object name.
//     It fails if it overflows the representation of the Go float type.
//     If the format is "nonfinite", then the JSON strings
//     "NaN", "Infinity", and "-Infinity" are decoded as NaN, +Inf, and -Inf.
//     Otherwise, the presence of such strings results in a [SemanticError].
//
//   - A Go map is decoded from a JSON object,
//     where each JSON object name and value pair is recursively decoded
//     as the Go map key and value. Maps are not cleared.
//     If the Go map is nil, then a new map is allocated to decode into.
//     If the decoded key matches an existing Go map entry, the entry value
//     is reused by decoding the JSON object value into it.
//     The formats "emitnull" and "emitempty" have no effect when decoding.
//
//   - A Go struct is decoded from a JSON object.
//     See the “JSON Representation of Go structs” section
//     in the package-level documentation for more details.
//
//   - A Go slice is decoded from a JSON array, where each JSON element
//     is recursively decoded and appended to the Go slice.
//     Before appending into a Go slice, a new slice is allocated if it is nil,
//     otherwise the slice length is reset to zero.
//     The formats "emitnull" and "emitempty" have no effect when decoding.
//
//   - A Go array is decoded from a JSON array, where each JSON array element
//     is recursively decoded as each corresponding Go array element.
//     Each Go array element is zeroed before decoding into it.
//     It fails with a [SemanticError] if the JSON array does not contain
//     the exact same number of elements as the Go array.
//     It does not support any custom format flags.
//
//   - A Go pointer is decoded based on the JSON kind and underlying Go type.
//     If the input is a JSON null, then this stores a nil pointer.
//     Otherwise, it allocates a new underlying value if the pointer is nil,
//     and recursively JSON decodes into the underlying value.
//     Format flags are forwarded to the decoding of the underlying type.
//
//   - A Go interface is decoded based on the JSON kind and underlying Go type.
//     If the input is a JSON null, then this stores a nil interface value.
//     Otherwise, a nil interface value of an empty interface type is initialized
//     with a zero Go bool, string, float64, map[string]any, or []any if the
//     input is a JSON boolean, string, number, object, or array, respectively.
//     If the interface value is still nil, then this fails with a [SemanticError]
//     since decoding could not determine an appropriate Go type to decode into.
//     For example, unmarshaling into a nil io.Reader fails since
//     there is no concrete type to populate the interface value with.
//     Otherwise an underlying value exists and it recursively decodes
//     the JSON input into it. It does not support any custom format flags.
//
//   - A Go [time.Time] is decoded from a JSON string containing the time
//     formatted in RFC 3339 with nanosecond precision.
//     If the format matches one of the format constants declared in
//     the time package (e.g., RFC1123), then that format is used for parsing.
//     If the format is "unix", "unixmilli", "unixmicro", or "unixnano",
//     then the timestamp is decoded from an optionally fractional JSON number
//     of the number of seconds (or milliseconds, microseconds, or nanoseconds)
//     since the Unix epoch, which is January 1st, 1970 at 00:00:00 UTC.
//     Otherwise, the format is used as-is with [time.Time.Parse] if non-empty.
//
//   - A Go [time.Duration] currently has no default representation and
//     requires an explicit format to be specified.
//     If the format is "sec", "milli", "micro", or "nano",
//     then the duration is decoded from an optionally fractional JSON number
//     of the number of seconds (or milliseconds, microseconds, or nanoseconds).
//     If the format is "units", it is decoded from a JSON string parsed using
//     [time.ParseDuration] (e.g., "1h30m" for 1 hour 30 minutes).
//     If the format is "iso8601", it is decoded from a JSON string using the
//     ISO 8601 standard for durations (e.g., "PT1H30M" for 1 hour 30 minutes)
//     accepting only accurate units of hours, minutes, or seconds.
//
//   - All other Go types (e.g., complex numbers, channels, and functions)
//     have no default representation and result in a [SemanticError].
//
// In general, unmarshaling follows merge semantics (similar to RFC 7396)
// where the decoded Go value replaces the destination value
// for any JSON kind other than an object.
// For JSON objects, the input object is merged into the destination value
// where matching object members recursively apply merge semantics.
func Unmarshal(in []byte, out any, opts ...Options) (err error) {
	dec := export.GetBufferedDecoder(in, opts...)
	defer export.PutBufferedDecoder(dec)
	xd := export.Decoder(dec)
	err = unmarshalDecode(dec, out, &xd.Struct, true)
	if err != nil && xd.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) {
		return internal.TransformUnmarshalError(out, err)
	}
	return err
}

// UnmarshalRead deserializes a Go value from an [io.Reader] according to the
// provided unmarshal and decode options (while ignoring marshal or encode options).
// The input must be a single JSON value with optional whitespace interspersed.
// It consumes the entirety of [io.Reader] until [io.EOF] is encountered,
// without reporting an error for EOF. The output must be a non-nil pointer.
// See [Unmarshal] for details about the conversion of JSON into a Go value.
func UnmarshalRead(in io.Reader, out any, opts ...Options) (err error) {
	dec := export.GetStreamingDecoder(in, opts...)
	defer export.PutStreamingDecoder(dec)
	xd := export.Decoder(dec)
	err = unmarshalDecode(dec, out, &xd.Struct, true)
	if err != nil && xd.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) {
		return internal.TransformUnmarshalError(out, err)
	}
	return err
}

// UnmarshalDecode deserializes a Go value from a [jsontext.Decoder] according to
// the provided unmarshal options (while ignoring marshal, encode, or decode options).
// Any unmarshal options already specified on the [jsontext.Decoder]
// take lower precedence than the set of options provided by the caller.
// Unlike [Unmarshal] and [UnmarshalRead], decode options are ignored because
// they must have already been specified on the provided [jsontext.Decoder].
//
// The input may be a stream of zero or more JSON values,
// where this only unmarshals the next JSON value in the stream.
// If there are no more top-level JSON values, it reports [io.EOF].
// The output must be a non-nil pointer.
// See [Unmarshal] for details about the conversion of JSON into a Go value.
func UnmarshalDecode(in *jsontext.Decoder, out any, opts ...Options) (err error) {
	xd := export.Decoder(in)
	if len(opts) > 0 {
		optsOriginal := xd.Struct
		defer func() { xd.Struct = optsOriginal }()
		xd.Struct.JoinWithoutCoderOptions(opts...)
	}
	err = unmarshalDecode(in, out, &xd.Struct, false)
	if err != nil && xd.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) {
		return internal.TransformUnmarshalError(out, err)
	}
	return err
}

func unmarshalDecode(in *jsontext.Decoder, out any, uo *jsonopts.Struct, last bool) (err error) {
	v := reflect.ValueOf(out)
	if v.Kind() != reflect.Pointer || v.IsNil() {
		return &SemanticError{action: "unmarshal", GoType: reflect.TypeOf(out), Err: internal.ErrNonNilReference}
	}
	va := addressableValue{v.Elem(), false} // dereferenced pointer is always addressable
	t := va.Type()

	// In legacy semantics, the entirety of the next JSON value
	// was validated before attempting to unmarshal it.
	if uo.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) {
		if err := export.Decoder(in).CheckNextValue(last); err != nil {
			if err == io.EOF && last {
				offset := in.InputOffset() + int64(len(in.UnreadBuffer()))
				return &jsontext.SyntacticError{ByteOffset: offset, Err: io.ErrUnexpectedEOF}
			}
			return err
		}
	}

	// Lookup and call the unmarshal function for this type.
	unmarshal := lookupArshaler(t).unmarshal
	if uo.Unmarshalers != nil {
		unmarshal, _ = uo.Unmarshalers.(*Unmarshalers).lookup(unmarshal, t)
	}
	if err := unmarshal(in, va, uo); err != nil {
		if !uo.Flags.Get(jsonflags.AllowDuplicateNames) {
			export.Decoder(in).Tokens.InvalidateDisabledNamespaces()
		}
		if err == io.EOF && last {
			offset := in.InputOffset() + int64(len(in.UnreadBuffer()))
			return &jsontext.SyntacticError{ByteOffset: offset, Err: io.ErrUnexpectedEOF}
		}
		return err
	}
	if last {
		return export.Decoder(in).CheckEOF()
	}
	return nil
}

// addressableValue is a reflect.Value that is guaranteed to be addressable
// such that calling the Addr and Set methods do not panic.
//
// There is no compile magic that enforces this property,
// but rather the need to construct this type makes it easier to examine each
// construction site to ensure that this property is upheld.
type addressableValue struct {
	reflect.Value

	// forcedAddr reports whether this value is addressable
	// only through the use of [newAddressableValue].
	// This is only used for [jsonflags.CallMethodsWithLegacySemantics].
	forcedAddr bool
}

// newAddressableValue constructs a new addressable value of type t.
func newAddressableValue(t reflect.Type) addressableValue {
	return addressableValue{reflect.New(t).Elem(), true}
}

// TODO: Remove *jsonopts.Struct argument from [marshaler] and [unmarshaler].
// This can be directly accessed on the encoder or decoder.

// All marshal and unmarshal behavior is implemented using these signatures.
// The *jsonopts.Struct argument is guaranteed to be identical to or at least
// a strict super-set of the options in Encoder.Struct or Decoder.Struct.
// It is identical for Marshal, Unmarshal, MarshalWrite, and UnmarshalRead.
// It is a super-set for MarshalEncode and UnmarshalDecode.
type (
	marshaler   = func(*jsontext.Encoder, addressableValue, *jsonopts.Struct) error
	unmarshaler = func(*jsontext.Decoder, addressableValue, *jsonopts.Struct) error
)

type arshaler struct {
	marshal    marshaler
	unmarshal  unmarshaler
	nonDefault bool
}

var lookupArshalerCache sync.Map // map[reflect.Type]*arshaler

func lookupArshaler(t reflect.Type) *arshaler {
	if v, ok := lookupArshalerCache.Load(t); ok {
		return v.(*arshaler)
	}

	fncs := makeDefaultArshaler(t)
	fncs = makeMethodArshaler(fncs, t)
	fncs = makeTimeArshaler(fncs, t)

	// Use the last stored so that duplicate arshalers can be garbage collected.
	v, _ := lookupArshalerCache.LoadOrStore(t, fncs)
	return v.(*arshaler)
}

var stringsPools = &sync.Pool{New: func() any { return new(stringSlice) }}

type stringSlice []string

// getStrings returns a non-nil pointer to a slice with length n.
func getStrings(n int) *stringSlice {
	s := stringsPools.Get().(*stringSlice)
	if cap(*s) < n {
		*s = make([]string, n)
	}
	*s = (*s)[:n]
	return s
}

func putStrings(s *stringSlice) {
	if cap(*s) > 1<<10 {
		*s = nil // avoid pinning arbitrarily large amounts of memory
	}
	clear(*s) // avoid pinning a reference to each string
	stringsPools.Put(s)
}
