// Code generated by tools/cmd/genoptions/main.go. DO NOT EDIT.

package jws

import (
	"context"
	"io"
	"io/fs"

	"github.com/lestrrat-go/option/v2"
)

type Option = option.Interface

// CompactOption describes options that can be passed to `jws.Compact`
type CompactOption interface {
	Option
	compactOption()
}

type compactOption struct {
	Option
}

func (*compactOption) compactOption() {}

// GlobalOption can be passed to `jws.Settings()` to set global options for the JWS package.
type GlobalOption interface {
	Option
	globalOption()
}

type globalOption struct {
	Option
}

func (*globalOption) globalOption() {}

// GlobalParseOption describes an Option that can be passed to `jws.Settings()`,
// `jws.Parse()`, and `jws.ReadFile()`.
type GlobalParseOption interface {
	Option
	globalOption()
	parseOption()
	readFileOption()
}

type globalParseOption struct {
	Option
}

func (*globalParseOption) globalOption() {}

func (*globalParseOption) parseOption() {}

func (*globalParseOption) readFileOption() {}

// ReadFileOption is a type of `Option` that can be passed to `jwe.Parse`
type ParseOption interface {
	Option
	readFileOption()
}

type parseOption struct {
	Option
}

func (*parseOption) readFileOption() {}

// ReadFileOption is a type of `Option` that can be passed to `jws.ReadFile`
type ReadFileOption interface {
	Option
	readFileOption()
}

type readFileOption struct {
	Option
}

func (*readFileOption) readFileOption() {}

// SignOption describes options that can be passed to `jws.Sign`
type SignOption interface {
	Option
	signOption()
}

type signOption struct {
	Option
}

func (*signOption) signOption() {}

// SignVerifyCompactOption describes options that can be passed to either `jws.Verify`,
// `jws.Sign`, or `jws.Compact`
type SignVerifyCompactOption interface {
	Option
	signOption()
	verifyOption()
	compactOption()
	parseOption()
}

type signVerifyCompactOption struct {
	Option
}

func (*signVerifyCompactOption) signOption() {}

func (*signVerifyCompactOption) verifyOption() {}

func (*signVerifyCompactOption) compactOption() {}

func (*signVerifyCompactOption) parseOption() {}

// SignVerifyOption describes options that can be passed to either `jws.Verify` or `jws.Sign`
type SignVerifyOption interface {
	Option
	signOption()
	verifyOption()
	parseOption()
}

type signVerifyOption struct {
	Option
}

func (*signVerifyOption) signOption() {}

func (*signVerifyOption) verifyOption() {}

func (*signVerifyOption) parseOption() {}

type SignVerifyParseOption interface {
	Option
	signOption()
	verifyOption()
	parseOption()
	readFileOption()
}

type signVerifyParseOption struct {
	Option
}

func (*signVerifyParseOption) signOption() {}

func (*signVerifyParseOption) verifyOption() {}

func (*signVerifyParseOption) parseOption() {}

func (*signVerifyParseOption) readFileOption() {}

// VerifyOption describes options that can be passed to `jws.Verify`
type VerifyOption interface {
	Option
	verifyOption()
	parseOption()
}

type verifyOption struct {
	Option
}

func (*verifyOption) verifyOption() {}

func (*verifyOption) parseOption() {}

// JSONSuboption describes suboptions that can be passed to the `jws.WithJSON()` option.
type WithJSONSuboption interface {
	Option
	withJSONSuboption()
}

type withJSONSuboption struct {
	Option
}

func (*withJSONSuboption) withJSONSuboption() {}

// WithKeySetSuboption is a suboption passed to the `jws.WithKeySet()` option
type WithKeySetSuboption interface {
	Option
	withKeySetSuboption()
}

type withKeySetSuboption struct {
	Option
}

func (*withKeySetSuboption) withKeySetSuboption() {}

// WithKeySuboption describes option types that can be passed to the `jws.WithKey()`
// option.
type WithKeySuboption interface {
	Option
	withKeySuboption()
}

type withKeySuboption struct {
	Option
}

func (*withKeySuboption) withKeySuboption() {}

type identBase64Encoder struct{}
type identContext struct{}
type identCritValidation struct{}
type identDetached struct{}
type identDetachedPayload struct{}
type identDetachedPayloadReader struct{}
type identFS struct{}
type identInferAlgorithmFromKey struct{}
type identKey struct{}
type identKeyProvider struct{}
type identKeyUsed struct{}
type identLegacySigners struct{}
type identMaxSignatures struct{}
type identMessage struct{}
type identMultipleKeysPerKeyID struct{}
type identPretty struct{}
type identProtectedHeaders struct{}
type identPublicHeaders struct{}
type identRequireKid struct{}
type identSerialization struct{}
type identUseDefault struct{}
type identValidateKey struct{}

func (identBase64Encoder) String() string {
	return "WithBase64Encoder"
}

func (identContext) String() string {
	return "WithContext"
}

func (identCritValidation) String() string {
	return "WithCritValidation"
}

func (identDetached) String() string {
	return "WithDetached"
}

func (identDetachedPayload) String() string {
	return "WithDetachedPayload"
}

func (identDetachedPayloadReader) String() string {
	return "WithDetachedPayloadReader"
}

func (identFS) String() string {
	return "WithFS"
}

func (identInferAlgorithmFromKey) String() string {
	return "WithInferAlgorithmFromKey"
}

func (identKey) String() string {
	return "WithKey"
}

func (identKeyProvider) String() string {
	return "WithKeyProvider"
}

func (identKeyUsed) String() string {
	return "WithKeyUsed"
}

func (identLegacySigners) String() string {
	return "WithLegacySigners"
}

func (identMaxSignatures) String() string {
	return "WithMaxSignatures"
}

func (identMessage) String() string {
	return "WithMessage"
}

func (identMultipleKeysPerKeyID) String() string {
	return "WithMultipleKeysPerKeyID"
}

func (identPretty) String() string {
	return "WithPretty"
}

func (identProtectedHeaders) String() string {
	return "WithProtectedHeaders"
}

func (identPublicHeaders) String() string {
	return "WithPublicHeaders"
}

func (identRequireKid) String() string {
	return "WithRequireKid"
}

func (identSerialization) String() string {
	return "WithSerialization"
}

func (identUseDefault) String() string {
	return "WithUseDefault"
}

func (identValidateKey) String() string {
	return "WithValidateKey"
}

// WithBase64Encoder specifies the base64 encoder to be used while signing or
// verifying the JWS message. By default, the raw URL base64 encoding (no padding)
// is used.
func WithBase64Encoder(v Base64Encoder) SignVerifyCompactOption {
	return &signVerifyCompactOption{option.New(identBase64Encoder{}, v)}
}

// WithContext attaches a context.Context to the verify call. The
// context is observed at three layers:
//
//   - jws.Verify (slow path) checks ctx.Err() between each signature,
//     each key provider, and each (alg, key) attempt — a deadline
//     fired between iterations short-circuits the loop with the
//     context error.
//   - jkuProvider.FetchKeys passes ctx to jwk.Fetcher.Fetch.
//   - The streaming detached-payload path checks ctx between Reads
//     of the caller's payload reader.
//
// staticKeyProvider and keySetProvider do not themselves consult
// ctx inside FetchKeys (the backing data is already in memory);
// cancellation observation between key candidates is handled by
// Verify's loop checks above.
func WithContext(v context.Context) VerifyOption {
	return &verifyOption{option.New(identContext{}, v)}
}

// WithCritValidation enables RFC 7515 Section 4.1.11 validation of the
// "crit" (Critical) header parameter during verification. The default
// is false, matching the behavior of v3.0.13 and earlier (the "crit"
// header is silently ignored).
//
// When enabled, jws.Verify() will reject any JWS whose protected
// header lists "crit" entries that the recipient has not declared
// support for via jws.WithCritExtension(). It will also reject
// structurally invalid "crit" lists: empty arrays, duplicate names,
// empty extension names, names of standard JOSE header parameters,
// and names that do not appear as header parameters in the protected
// header.
//
// Per RFC 7515 Section 4.1.11, recipients MUST reject a JWS whose
// "crit" list names extensions they do not understand. Enabling this
// option together with one or more jws.WithCritExtension() calls is
// the only way to satisfy that requirement with this library.
//
// IMPORTANT: enabling this option makes the library check that every
// "crit" entry has been declared via jws.WithCritExtension(), but the
// library cannot perform the actual extension-specific processing on
// your behalf. After jws.Verify() returns successfully, your code
// MUST read each declared extension header and apply whatever check
// or side effect the extension semantics demand. If you declare an
// extension and then forget to act on its value, you have defeated
// the protection the producer was trying to obtain by marking that
// extension critical. See the documentation on jws.WithCritExtension
// for details.
func WithCritValidation(v bool) VerifyOption {
	return &verifyOption{option.New(identCritValidation{}, v)}
}

// WithDetached specifies that the `jws.Message` should be serialized in
// JWS compact serialization with detached payload. The resulting octet
// sequence will not contain the payload section.
func WithDetached(v bool) CompactOption {
	return &compactOption{option.New(identDetached{}, v)}
}

// WithDetachedPayload can be used to both sign or verify a JWS message with a
// detached payload.
// Note that this option does NOT populate the `b64` header, which is sometimes
// required by other JWS implementations.
//
// When this option is used for `jws.Sign()`, the first parameter (normally the payload)
// must be set to `nil`.
//
// When passed to `jws.Verify()` together with `jws.WithCritValidation(true)`,
// the RFC 7797 `"b64"` extension is automatically added to the
// caller's allowlist as if `jws.WithCritExtension("b64")` had also
// been passed. Detached-payload verification is the canonical
// pairing for `b64=false`, and the jws package implements `b64=false`
// handling natively, so there is no need to declare it explicitly.
// Other crit extensions still require explicit declaration.
//
// If you have to verify using this option, you should know exactly how and why this works.
func WithDetachedPayload(v []byte) SignVerifyOption {
	return &signVerifyOption{option.New(identDetachedPayload{}, v)}
}

// WithDetachedPayloadReader is the streaming variant of
// `jws.WithDetachedPayload()`: the detached payload is consumed from an
// `io.Reader` instead of a `[]byte`. Use this when the detached payload
// is too large to comfortably materialize in memory.
//
// For detached payloads that already fit in memory, prefer
// `jws.WithDetachedPayload()`; the byte-slice path supports the full
// option and algorithm surface, while the Reader path is a narrow
// specialist.
//
// The Reader is consumed exactly once. On signing or verification
// failure the Reader cannot be rewound; callers that need retry
// semantics must buffer the payload themselves.
//
// The Reader is accessed from the calling goroutine only; do not share
// a single Reader between concurrent `jws.Sign` / `jws.Verify` calls
// unless the Reader is itself goroutine-safe and positioned
// independently for each call.
//
// Only the HMAC, RSA (PKCS#1 v1.5 and PSS), and ECDSA algorithm
// families are supported by this option; EdDSA and custom-family
// algorithms require the full payload in memory and will be rejected
// with a clear error. The option is mutually exclusive with
// `jws.WithDetachedPayload()` and `jws.WithInsecureNoSignature()`.
// Algorithms registered via `jws.RegisterSigner()` /
// `jws.RegisterVerifier()` are likewise unreachable through this
// path (the streaming code dispatches directly against the dsig
// algorithm registry).
//
// On sign, multiple `jws.WithKey()` options may be combined with
// `jws.WithJSON()` to produce a general-form multi-signature JWS;
// the payload is streamed once and fanned out to each signer. All
// signers must agree on the RFC 7797 `"b64"` flag, since the
// produced JWS has a single payload segment on the wire. Compact
// serialization still allows exactly one signature.
//
// On verify, this option supports only single-signature JWS input
// (compact or flattened/general-single-signature JSON). To verify
// one signature out of a multi-signature JWS, use `jws.Verify()`
// with `jws.WithDetachedPayload()` and a buffered copy of the
// payload.
//
// On verify, `jws.Verify()` returns a non-nil zero-length `[]byte` on
// success when this option is used, because the payload was streamed
// from the caller rather than extracted from the JWS envelope. Do not
// read that slice as "the payload is empty" — the verified bytes are
// whatever the caller read from the Reader, and callers that need
// them must retain their own copy.
//
// `jws.WithBase64Encoder()` is honored as long as the supplied
// encoder implements `jws.Base64StreamEncoder` (i.e. provides a
// stream-capable `NewEncoder(io.Writer) io.WriteCloser`). The
// default encoder (`encoding/base64.RawURLEncoding`) satisfies
// this automatically. Custom encoders that only implement the
// basic `jws.Base64Encoder` interface cause `jws.Sign()` /
// `jws.Verify()` to return an error when combined with this
// option, rather than silently falling back to a different encoder
// for the payload.
//
// Like `jws.WithDetachedPayload()`, on verify this option
// implicitly declares RFC 7797 `"b64"` as a recognized `crit`
// extension.
//
// When this option is used with `jws.Sign()`, the first parameter
// (normally the payload) must be set to `nil`.
func WithDetachedPayloadReader(v io.Reader) SignVerifyOption {
	return &signVerifyOption{option.New(identDetachedPayloadReader{}, v)}
}

// WithFS specifies the source `fs.FS` object to read the file from.
func WithFS(v fs.FS) ReadFileOption {
	return &readFileOption{option.New(identFS{}, v)}
}

// WithInferAlgorithmFromKey specifies whether the JWS signing algorithm name
// should be inferred by looking at the provided key, in case the JWS
// message or the key does not have a proper `alg` header.
//
// When this option is set to true, a list of algorithm(s) that is compatible
// with the key type will be enumerated, and _ALL_ of them will be tried
// against the key/message pair. If any of them succeeds, the verification
// will be considered successful.
//
// Compared to providing explicit `alg` from the key this is slower, and
// verification may fail to verify if somehow our heuristics are wrong
// or outdated.
//
// Also, automatic detection of signature verification methods are always
// more vulnerable for potential attack vectors.
//
// It is highly recommended that you fix your key to contain a proper `alg`
// header field instead of resorting to using this option, but sometimes
// it just needs to happen.
//
// Fan-out and DoS considerations: when combined with `WithRequireKid(false)`
// against a large JWKS, verification attempts scale with the number of
// keys in the set. If the JWS protected header advertises an `alg` (as
// required by RFC 7515 §4.1.1), only keys whose type is compatible with
// that algorithm are tried, so the cost is bounded by the number of
// type-compatible keys. If the header has no `alg`, every inferred
// algorithm is tried against every candidate key, and the cost becomes
// `N_keys × N_algs_per_keytype`. Operators exposing verification to
// untrusted input should pair this option with `WithMaxSignatures` and
// keep their JWKS bounded.
func WithInferAlgorithmFromKey(v bool) WithKeySetSuboption {
	return &withKeySetSuboption{option.New(identInferAlgorithmFromKey{}, v)}
}

func WithKeyProvider(v KeyProvider) VerifyOption {
	return &verifyOption{option.New(identKeyProvider{}, v)}
}

// WithKeyUsed allows you to specify the `jws.Verify()` function to
// return the key used for verification. This may be useful when
// you specify multiple key sources or if you pass a `jwk.Set`
// and you want to know which key was successful at verifying the
// signature.
//
// `v` must be a pointer to an empty `any`. Do not use
// `jwk.Key` here unless you are 100% sure that all keys that you
// have provided are instances of `jwk.Key` (remember that the
// jwx API allows users to specify a raw key such as *rsa.PublicKey)
func WithKeyUsed(v any) VerifyOption {
	return &verifyOption{option.New(identKeyUsed{}, v)}
}

// WithLegacySigners is a no-op option that exists only for backwards compatibility.
func WithLegacySigners() GlobalOption {
	return &globalOption{option.New(identLegacySigners{}, true)}
}

// WithMaxSignatures specifies the maximum number of signatures allowed
// in a JWS message using JSON serialization. If a JWS message contains
// more signatures than this value, parsing will return an error.
// The default value is 100.
//
// This option can be passed to `jws.Settings()` to change the default
// globally, or to `jws.Parse()` / `jws.ReadFile()` for a per-call
// override.
func WithMaxSignatures(v int) GlobalParseOption {
	return &globalParseOption{option.New(identMaxSignatures{}, v)}
}

// WithMessage can be passed to Verify() to obtain the jws.Message upon
// a successful verification.
func WithMessage(v *Message) VerifyOption {
	return &verifyOption{option.New(identMessage{}, v)}
}

// WithMultipleKeysPerKeyID specifies if we should expect multiple keys
// to match against a key ID. By default it is assumed that key IDs are
// unique, i.e. for a given key ID, the key set only contains a single
// key that has the matching ID. When this option is set to true,
// multiple keys that match the same key ID in the set can be tried.
func WithMultipleKeysPerKeyID(v bool) WithKeySetSuboption {
	return &withKeySetSuboption{option.New(identMultipleKeysPerKeyID{}, v)}
}

// WithPretty specifies whether the JSON output should be formatted and
// indented
func WithPretty(v bool) WithJSONSuboption {
	return &withJSONSuboption{option.New(identPretty{}, v)}
}

// WithProtected is used with `jws.WithKey()` option when used with `jws.Sign()`
// to specify a protected header to be attached to the JWS signature.
//
// It has no effect if used when `jws.WithKey()` is passed to `jws.Verify()`.
//
// kid precedence: if the supplied headers include a "kid" and the
// `jwk.Key` passed to `jws.WithKey()` also carries one, the
// `jwk.Key`'s kid wins and the header kid is silently overwritten.
// Callers that want to keep the header kid must strip it from the
// key first (e.g. `key.Remove(jwk.KeyIDKey)`).
func WithProtectedHeaders(v Headers) WithKeySuboption {
	return &withKeySuboption{option.New(identProtectedHeaders{}, v)}
}

// WithPublic is used with `jws.WithKey()` option when used with `jws.Sign()`
// to specify a public header to be attached to the JWS signature.
//
// It has no effect if used when `jws.WithKey()` is passed to `jws.Verify()`
//
// `jws.Sign()` will result in an error if `jws.WithPublic()` is used
// and the serialization format is compact serialization.
func WithPublicHeaders(v Headers) WithKeySuboption {
	return &withKeySuboption{option.New(identPublicHeaders{}, v)}
}

// WithRequiredKid specifies whether the keys in the jwk.Set should
// only be matched if the target JWS message's Key ID and the Key ID
// in the given key matches.
func WithRequireKid(v bool) WithKeySetSuboption {
	return &withKeySetSuboption{option.New(identRequireKid{}, v)}
}

// WithCompact specifies that the result of `jws.Sign()` is serialized in
// compact format.
//
// By default `jws.Sign()` will opt to use compact format, so you usually
// do not need to specify this option other than to be explicit about it
func WithCompact() SignVerifyParseOption {
	return &signVerifyParseOption{option.New(identSerialization{}, fmtCompact)}
}

// WithUseDefault specifies that if and only if a jwk.Key contains
// exactly one jwk.Key, that key should be used.
func WithUseDefault(v bool) WithKeySetSuboption {
	return &withKeySetSuboption{option.New(identUseDefault{}, v)}
}

// WithValidateKey specifies whether the key used for signing or verification
// should be validated before using. Note that this means calling
// `key.Validate()` on the key, which in turn means that your key
// must be a `jwk.Key` instance, or a key that can be converted to
// a `jwk.Key` by calling `jwk.Import()`. This means that your
// custom hardware-backed keys will probably not work.
//
// You can directly call `key.Validate()` yourself if you need to
// mix keys that cannot be converted to `jwk.Key`.
//
// Please also note that use of this option will also result in
// one extra conversion of raw keys to a `jwk.Key` instance. If you
// care about shaving off as much as possible, consider using a
// pre-validated key instead of using this option to validate
// the key on-demand each time.
//
// By default, the key is not validated.
func WithValidateKey(v bool) SignVerifyOption {
	return &signVerifyOption{option.New(identValidateKey{}, v)}
}
