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

package openid

import (
	"bytes"
	"fmt"
	"sort"
	"sync"
	"time"

	"github.com/lestrrat-go/blackmagic"
	"github.com/lestrrat-go/jwx/v3/internal/json"
	"github.com/lestrrat-go/jwx/v3/internal/pool"
	"github.com/lestrrat-go/jwx/v3/internal/tokens"
	"github.com/lestrrat-go/jwx/v3/jwt"
	jwterrs "github.com/lestrrat-go/jwx/v3/jwt/internal/errors"
	"github.com/lestrrat-go/jwx/v3/jwt/internal/types"
)

const (
	AddressKey             = "address"
	AudienceKey            = "aud"
	BirthdateKey           = "birthdate"
	EmailKey               = "email"
	EmailVerifiedKey       = "email_verified"
	ExpirationKey          = "exp"
	FamilyNameKey          = "family_name"
	GenderKey              = "gender"
	GivenNameKey           = "given_name"
	IssuedAtKey            = "iat"
	IssuerKey              = "iss"
	JwtIDKey               = "jti"
	LocaleKey              = "locale"
	MiddleNameKey          = "middle_name"
	NameKey                = "name"
	NicknameKey            = "nickname"
	NotBeforeKey           = "nbf"
	PhoneNumberKey         = "phone_number"
	PhoneNumberVerifiedKey = "phone_number_verified"
	PictureKey             = "picture"
	PreferredUsernameKey   = "preferred_username"
	ProfileKey             = "profile"
	SubjectKey             = "sub"
	UpdatedAtKey           = "updated_at"
	WebsiteKey             = "website"
	ZoneinfoKey            = "zoneinfo"
)

// stdClaimNames is a list of all standard claim names defined in the JWT specification.
var stdClaimNames = []string{AddressKey, AudienceKey, BirthdateKey, EmailKey, EmailVerifiedKey, ExpirationKey, FamilyNameKey, GenderKey, GivenNameKey, IssuedAtKey, IssuerKey, JwtIDKey, LocaleKey, MiddleNameKey, NameKey, NicknameKey, NotBeforeKey, PhoneNumberKey, PhoneNumberVerifiedKey, PictureKey, PreferredUsernameKey, ProfileKey, SubjectKey, UpdatedAtKey, WebsiteKey, ZoneinfoKey}

type Token interface {
	// Address returns the value for "address" field of the token
	Address() (*AddressClaim, bool)

	// Audience returns the value for "aud" field of the token
	Audience() ([]string, bool)

	// Birthdate returns the value for "birthdate" field of the token
	Birthdate() (*BirthdateClaim, bool)

	// Email returns the value for "email" field of the token
	Email() (string, bool)

	// EmailVerified returns the value for "email_verified" field of the token
	EmailVerified() (bool, bool)

	// Expiration returns the value for "exp" field of the token
	Expiration() (time.Time, bool)

	// FamilyName returns the value for "family_name" field of the token
	FamilyName() (string, bool)

	// Gender returns the value for "gender" field of the token
	Gender() (string, bool)

	// GivenName returns the value for "given_name" field of the token
	GivenName() (string, bool)

	// IssuedAt returns the value for "iat" field of the token
	IssuedAt() (time.Time, bool)

	// Issuer returns the value for "iss" field of the token
	Issuer() (string, bool)

	// JwtID returns the value for "jti" field of the token
	JwtID() (string, bool)

	// Locale returns the value for "locale" field of the token
	Locale() (string, bool)

	// MiddleName returns the value for "middle_name" field of the token
	MiddleName() (string, bool)

	// Name returns the value for "name" field of the token
	Name() (string, bool)

	// Nickname returns the value for "nickname" field of the token
	Nickname() (string, bool)

	// NotBefore returns the value for "nbf" field of the token
	NotBefore() (time.Time, bool)

	// PhoneNumber returns the value for "phone_number" field of the token
	PhoneNumber() (string, bool)

	// PhoneNumberVerified returns the value for "phone_number_verified" field of the token
	PhoneNumberVerified() (bool, bool)

	// Picture returns the value for "picture" field of the token
	Picture() (string, bool)

	// PreferredUsername returns the value for "preferred_username" field of the token
	PreferredUsername() (string, bool)

	// Profile returns the value for "profile" field of the token
	Profile() (string, bool)

	// Subject returns the value for "sub" field of the token
	Subject() (string, bool)

	// UpdatedAt returns the value for "updated_at" field of the token
	UpdatedAt() (time.Time, bool)

	// Website returns the value for "website" field of the token
	Website() (string, bool)

	// Zoneinfo returns the value for "zoneinfo" field of the token
	Zoneinfo() (string, bool)

	// Get is used to extract the value of any claim, including non-standard claims, out of the token.
	//
	// The first argument is the name of the claim. The second argument is a pointer
	// to a variable that will receive the value of the claim. The method returns
	// an error if the claim does not exist, or if the value cannot be assigned to
	// the destination variable.  Note that a field is considered to "exist" even if
	// the value is empty-ish (e.g. 0, false, ""), as long as it is explicitly set.
	//
	// For standard claims, you can use the corresponding getter method, such as
	// `Issuer()`, `Subject()`, `Audience()`, `IssuedAt()`, `NotBefore()`, `ExpiresAt()`
	//
	// Note that fields of JWS/JWE are NOT accessible through this method. You need
	// to use `jws.Parse` and `jwe.Parse` to obtain the JWS/JWE message (and NOT
	// the payload, which presumably is the JWT), and then use their `Get` methods in their respective packages
	Get(string, any) error

	// Set assigns a value to the corresponding field in the token. Some
	// pre-defined fields such as `nbf`, `iat`, `iss` need their values to
	// be of a specific type. See the other getter methods in this interface
	// for the types of each of these fields
	Set(string, any) error

	// Has returns true if the specified claim has a value, even if
	// the value is empty-ish (e.g. 0, false, "")  as long as it has been
	// explicitly set.
	Has(string) bool
	Remove(string) error

	// Options returns the per-token options associated with this token.
	// The options set value will be copied when the token is cloned via `Clone()`
	// but it will not survive when the token goes through marshaling/unmarshaling
	// such as `json.Marshal` and `json.Unmarshal`
	Options() *jwt.TokenOptionSet
	Clone() (jwt.Token, error)
	Keys() []string
}
type stdToken struct {
	mu                  *sync.RWMutex
	dc                  DecodeCtx          // per-object context for decoding
	options             jwt.TokenOptionSet // per-object option
	address             *AddressClaim
	audience            types.StringList // https://tools.ietf.org/html/rfc7519#section-4.1.3
	birthdate           *BirthdateClaim
	email               *string
	emailVerified       *bool
	expiration          *types.NumericDate // https://tools.ietf.org/html/rfc7519#section-4.1.4
	familyName          *string
	gender              *string
	givenName           *string
	issuedAt            *types.NumericDate // https://tools.ietf.org/html/rfc7519#section-4.1.6
	issuer              *string            // https://tools.ietf.org/html/rfc7519#section-4.1.1
	jwtID               *string            // https://tools.ietf.org/html/rfc7519#section-4.1.7
	locale              *string
	middleName          *string
	name                *string
	nickname            *string
	notBefore           *types.NumericDate // https://tools.ietf.org/html/rfc7519#section-4.1.5
	phoneNumber         *string
	phoneNumberVerified *bool
	picture             *string
	preferredUsername   *string
	profile             *string
	subject             *string // https://tools.ietf.org/html/rfc7519#section-4.1.2
	updatedAt           *types.NumericDate
	website             *string
	zoneinfo            *string
	privateClaims       map[string]any
}

// New creates a standard token, with minimal knowledge of
// possible claims. Standard claims include"address", "aud", "birthdate", "email", "email_verified", "exp", "family_name", "gender", "given_name", "iat", "iss", "jti", "locale", "middle_name", "name", "nickname", "nbf", "phone_number", "phone_number_verified", "picture", "preferred_username", "profile", "sub", "updated_at", "website" and "zoneinfo".
// Convenience accessors are provided for these standard claims
func New() Token {
	return &stdToken{
		mu:            &sync.RWMutex{},
		privateClaims: make(map[string]any),
		options:       jwt.DefaultOptionSet(),
	}
}

func (t *stdToken) Options() *jwt.TokenOptionSet {
	return &t.options
}

func (t *stdToken) Has(name string) bool {
	t.mu.RLock()
	defer t.mu.RUnlock()
	switch name {
	case AddressKey:
		return t.address != nil
	case AudienceKey:
		return t.audience != nil
	case BirthdateKey:
		return t.birthdate != nil
	case EmailKey:
		return t.email != nil
	case EmailVerifiedKey:
		return t.emailVerified != nil
	case ExpirationKey:
		return t.expiration != nil
	case FamilyNameKey:
		return t.familyName != nil
	case GenderKey:
		return t.gender != nil
	case GivenNameKey:
		return t.givenName != nil
	case IssuedAtKey:
		return t.issuedAt != nil
	case IssuerKey:
		return t.issuer != nil
	case JwtIDKey:
		return t.jwtID != nil
	case LocaleKey:
		return t.locale != nil
	case MiddleNameKey:
		return t.middleName != nil
	case NameKey:
		return t.name != nil
	case NicknameKey:
		return t.nickname != nil
	case NotBeforeKey:
		return t.notBefore != nil
	case PhoneNumberKey:
		return t.phoneNumber != nil
	case PhoneNumberVerifiedKey:
		return t.phoneNumberVerified != nil
	case PictureKey:
		return t.picture != nil
	case PreferredUsernameKey:
		return t.preferredUsername != nil
	case ProfileKey:
		return t.profile != nil
	case SubjectKey:
		return t.subject != nil
	case UpdatedAtKey:
		return t.updatedAt != nil
	case WebsiteKey:
		return t.website != nil
	case ZoneinfoKey:
		return t.zoneinfo != nil
	default:
		_, ok := t.privateClaims[name]
		return ok
	}
}

func (t *stdToken) Get(name string, dst any) error {
	t.mu.RLock()
	defer t.mu.RUnlock()
	switch name {
	case AddressKey:
		if t.address == nil {
			return jwterrs.ClaimNotFoundError{Name: name}
		}
		if err := blackmagic.AssignIfCompatible(dst, t.address); err != nil {
			return jwterrs.ClaimAssignmentFailedError{Err: err}
		}
		return nil
	case AudienceKey:
		if t.audience == nil {
			return jwterrs.ClaimNotFoundError{Name: name}
		}
		if err := blackmagic.AssignIfCompatible(dst, t.audience.Get()); err != nil {
			return jwterrs.ClaimAssignmentFailedError{Err: err}
		}
		return nil
	case BirthdateKey:
		if t.birthdate == nil {
			return jwterrs.ClaimNotFoundError{Name: name}
		}
		if err := blackmagic.AssignIfCompatible(dst, t.birthdate); err != nil {
			return jwterrs.ClaimAssignmentFailedError{Err: err}
		}
		return nil
	case EmailKey:
		if t.email == nil {
			return jwterrs.ClaimNotFoundError{Name: name}
		}
		if err := blackmagic.AssignIfCompatible(dst, *(t.email)); err != nil {
			return jwterrs.ClaimAssignmentFailedError{Err: err}
		}
		return nil
	case EmailVerifiedKey:
		if t.emailVerified == nil {
			return jwterrs.ClaimNotFoundError{Name: name}
		}
		if err := blackmagic.AssignIfCompatible(dst, *(t.emailVerified)); err != nil {
			return jwterrs.ClaimAssignmentFailedError{Err: err}
		}
		return nil
	case ExpirationKey:
		if t.expiration == nil {
			return jwterrs.ClaimNotFoundError{Name: name}
		}
		if err := blackmagic.AssignIfCompatible(dst, t.expiration.Get()); err != nil {
			return jwterrs.ClaimAssignmentFailedError{Err: err}
		}
		return nil
	case FamilyNameKey:
		if t.familyName == nil {
			return jwterrs.ClaimNotFoundError{Name: name}
		}
		if err := blackmagic.AssignIfCompatible(dst, *(t.familyName)); err != nil {
			return jwterrs.ClaimAssignmentFailedError{Err: err}
		}
		return nil
	case GenderKey:
		if t.gender == nil {
			return jwterrs.ClaimNotFoundError{Name: name}
		}
		if err := blackmagic.AssignIfCompatible(dst, *(t.gender)); err != nil {
			return jwterrs.ClaimAssignmentFailedError{Err: err}
		}
		return nil
	case GivenNameKey:
		if t.givenName == nil {
			return jwterrs.ClaimNotFoundError{Name: name}
		}
		if err := blackmagic.AssignIfCompatible(dst, *(t.givenName)); err != nil {
			return jwterrs.ClaimAssignmentFailedError{Err: err}
		}
		return nil
	case IssuedAtKey:
		if t.issuedAt == nil {
			return jwterrs.ClaimNotFoundError{Name: name}
		}
		if err := blackmagic.AssignIfCompatible(dst, t.issuedAt.Get()); err != nil {
			return jwterrs.ClaimAssignmentFailedError{Err: err}
		}
		return nil
	case IssuerKey:
		if t.issuer == nil {
			return jwterrs.ClaimNotFoundError{Name: name}
		}
		if err := blackmagic.AssignIfCompatible(dst, *(t.issuer)); err != nil {
			return jwterrs.ClaimAssignmentFailedError{Err: err}
		}
		return nil
	case JwtIDKey:
		if t.jwtID == nil {
			return jwterrs.ClaimNotFoundError{Name: name}
		}
		if err := blackmagic.AssignIfCompatible(dst, *(t.jwtID)); err != nil {
			return jwterrs.ClaimAssignmentFailedError{Err: err}
		}
		return nil
	case LocaleKey:
		if t.locale == nil {
			return jwterrs.ClaimNotFoundError{Name: name}
		}
		if err := blackmagic.AssignIfCompatible(dst, *(t.locale)); err != nil {
			return jwterrs.ClaimAssignmentFailedError{Err: err}
		}
		return nil
	case MiddleNameKey:
		if t.middleName == nil {
			return jwterrs.ClaimNotFoundError{Name: name}
		}
		if err := blackmagic.AssignIfCompatible(dst, *(t.middleName)); err != nil {
			return jwterrs.ClaimAssignmentFailedError{Err: err}
		}
		return nil
	case NameKey:
		if t.name == nil {
			return jwterrs.ClaimNotFoundError{Name: name}
		}
		if err := blackmagic.AssignIfCompatible(dst, *(t.name)); err != nil {
			return jwterrs.ClaimAssignmentFailedError{Err: err}
		}
		return nil
	case NicknameKey:
		if t.nickname == nil {
			return jwterrs.ClaimNotFoundError{Name: name}
		}
		if err := blackmagic.AssignIfCompatible(dst, *(t.nickname)); err != nil {
			return jwterrs.ClaimAssignmentFailedError{Err: err}
		}
		return nil
	case NotBeforeKey:
		if t.notBefore == nil {
			return jwterrs.ClaimNotFoundError{Name: name}
		}
		if err := blackmagic.AssignIfCompatible(dst, t.notBefore.Get()); err != nil {
			return jwterrs.ClaimAssignmentFailedError{Err: err}
		}
		return nil
	case PhoneNumberKey:
		if t.phoneNumber == nil {
			return jwterrs.ClaimNotFoundError{Name: name}
		}
		if err := blackmagic.AssignIfCompatible(dst, *(t.phoneNumber)); err != nil {
			return jwterrs.ClaimAssignmentFailedError{Err: err}
		}
		return nil
	case PhoneNumberVerifiedKey:
		if t.phoneNumberVerified == nil {
			return jwterrs.ClaimNotFoundError{Name: name}
		}
		if err := blackmagic.AssignIfCompatible(dst, *(t.phoneNumberVerified)); err != nil {
			return jwterrs.ClaimAssignmentFailedError{Err: err}
		}
		return nil
	case PictureKey:
		if t.picture == nil {
			return jwterrs.ClaimNotFoundError{Name: name}
		}
		if err := blackmagic.AssignIfCompatible(dst, *(t.picture)); err != nil {
			return jwterrs.ClaimAssignmentFailedError{Err: err}
		}
		return nil
	case PreferredUsernameKey:
		if t.preferredUsername == nil {
			return jwterrs.ClaimNotFoundError{Name: name}
		}
		if err := blackmagic.AssignIfCompatible(dst, *(t.preferredUsername)); err != nil {
			return jwterrs.ClaimAssignmentFailedError{Err: err}
		}
		return nil
	case ProfileKey:
		if t.profile == nil {
			return jwterrs.ClaimNotFoundError{Name: name}
		}
		if err := blackmagic.AssignIfCompatible(dst, *(t.profile)); err != nil {
			return jwterrs.ClaimAssignmentFailedError{Err: err}
		}
		return nil
	case SubjectKey:
		if t.subject == nil {
			return jwterrs.ClaimNotFoundError{Name: name}
		}
		if err := blackmagic.AssignIfCompatible(dst, *(t.subject)); err != nil {
			return jwterrs.ClaimAssignmentFailedError{Err: err}
		}
		return nil
	case UpdatedAtKey:
		if t.updatedAt == nil {
			return jwterrs.ClaimNotFoundError{Name: name}
		}
		if err := blackmagic.AssignIfCompatible(dst, t.updatedAt.Get()); err != nil {
			return jwterrs.ClaimAssignmentFailedError{Err: err}
		}
		return nil
	case WebsiteKey:
		if t.website == nil {
			return jwterrs.ClaimNotFoundError{Name: name}
		}
		if err := blackmagic.AssignIfCompatible(dst, *(t.website)); err != nil {
			return jwterrs.ClaimAssignmentFailedError{Err: err}
		}
		return nil
	case ZoneinfoKey:
		if t.zoneinfo == nil {
			return jwterrs.ClaimNotFoundError{Name: name}
		}
		if err := blackmagic.AssignIfCompatible(dst, *(t.zoneinfo)); err != nil {
			return jwterrs.ClaimAssignmentFailedError{Err: err}
		}
		return nil
	default:
		v, ok := t.privateClaims[name]
		if !ok {
			return jwterrs.ClaimNotFoundError{Name: name}
		}
		if err := blackmagic.AssignIfCompatible(dst, v); err != nil {
			return jwterrs.ClaimAssignmentFailedError{Err: err}
		}
		return nil
	}
}

func (t *stdToken) Remove(key string) error {
	t.mu.Lock()
	defer t.mu.Unlock()
	switch key {
	case AddressKey:
		t.address = nil
	case AudienceKey:
		t.audience = nil
	case BirthdateKey:
		t.birthdate = nil
	case EmailKey:
		t.email = nil
	case EmailVerifiedKey:
		t.emailVerified = nil
	case ExpirationKey:
		t.expiration = nil
	case FamilyNameKey:
		t.familyName = nil
	case GenderKey:
		t.gender = nil
	case GivenNameKey:
		t.givenName = nil
	case IssuedAtKey:
		t.issuedAt = nil
	case IssuerKey:
		t.issuer = nil
	case JwtIDKey:
		t.jwtID = nil
	case LocaleKey:
		t.locale = nil
	case MiddleNameKey:
		t.middleName = nil
	case NameKey:
		t.name = nil
	case NicknameKey:
		t.nickname = nil
	case NotBeforeKey:
		t.notBefore = nil
	case PhoneNumberKey:
		t.phoneNumber = nil
	case PhoneNumberVerifiedKey:
		t.phoneNumberVerified = nil
	case PictureKey:
		t.picture = nil
	case PreferredUsernameKey:
		t.preferredUsername = nil
	case ProfileKey:
		t.profile = nil
	case SubjectKey:
		t.subject = nil
	case UpdatedAtKey:
		t.updatedAt = nil
	case WebsiteKey:
		t.website = nil
	case ZoneinfoKey:
		t.zoneinfo = nil
	default:
		delete(t.privateClaims, key)
	}
	return nil
}

func (t *stdToken) Set(name string, value any) error {
	t.mu.Lock()
	defer t.mu.Unlock()
	return t.setNoLock(name, value)
}

func (t *stdToken) DecodeCtx() DecodeCtx {
	t.mu.RLock()
	defer t.mu.RUnlock()
	return t.dc
}

func (t *stdToken) SetDecodeCtx(v DecodeCtx) {
	t.mu.Lock()
	defer t.mu.Unlock()
	t.dc = v
}

func (t *stdToken) setNoLock(name string, value any) error {
	switch name {
	case AddressKey:
		var acceptor AddressClaim
		if err := acceptor.Accept(value); err != nil {
			return fmt.Errorf(`invalid value for %s key: %w`, AddressKey, err)
		}
		t.address = &acceptor
		return nil
	case AudienceKey:
		var acceptor types.StringList
		if err := acceptor.Accept(value); err != nil {
			return fmt.Errorf(`invalid value for %s key: %w`, AudienceKey, err)
		}
		t.audience = acceptor
		return nil
	case BirthdateKey:
		var acceptor BirthdateClaim
		if err := acceptor.Accept(value); err != nil {
			return fmt.Errorf(`invalid value for %s key: %w`, BirthdateKey, err)
		}
		t.birthdate = &acceptor
		return nil
	case EmailKey:
		if v, ok := value.(string); ok {
			t.email = &v
			return nil
		}
		return fmt.Errorf(`invalid value for %s key: %T`, EmailKey, value)
	case EmailVerifiedKey:
		if v, ok := value.(bool); ok {
			t.emailVerified = &v
			return nil
		}
		return fmt.Errorf(`invalid value for %s key: %T`, EmailVerifiedKey, value)
	case ExpirationKey:
		var acceptor types.NumericDate
		if err := acceptor.Accept(value); err != nil {
			return fmt.Errorf(`invalid value for %s key: %w`, ExpirationKey, err)
		}
		t.expiration = &acceptor
		return nil
	case FamilyNameKey:
		if v, ok := value.(string); ok {
			t.familyName = &v
			return nil
		}
		return fmt.Errorf(`invalid value for %s key: %T`, FamilyNameKey, value)
	case GenderKey:
		if v, ok := value.(string); ok {
			t.gender = &v
			return nil
		}
		return fmt.Errorf(`invalid value for %s key: %T`, GenderKey, value)
	case GivenNameKey:
		if v, ok := value.(string); ok {
			t.givenName = &v
			return nil
		}
		return fmt.Errorf(`invalid value for %s key: %T`, GivenNameKey, value)
	case IssuedAtKey:
		var acceptor types.NumericDate
		if err := acceptor.Accept(value); err != nil {
			return fmt.Errorf(`invalid value for %s key: %w`, IssuedAtKey, err)
		}
		t.issuedAt = &acceptor
		return nil
	case IssuerKey:
		if v, ok := value.(string); ok {
			t.issuer = &v
			return nil
		}
		return fmt.Errorf(`invalid value for %s key: %T`, IssuerKey, value)
	case JwtIDKey:
		if v, ok := value.(string); ok {
			t.jwtID = &v
			return nil
		}
		return fmt.Errorf(`invalid value for %s key: %T`, JwtIDKey, value)
	case LocaleKey:
		if v, ok := value.(string); ok {
			t.locale = &v
			return nil
		}
		return fmt.Errorf(`invalid value for %s key: %T`, LocaleKey, value)
	case MiddleNameKey:
		if v, ok := value.(string); ok {
			t.middleName = &v
			return nil
		}
		return fmt.Errorf(`invalid value for %s key: %T`, MiddleNameKey, value)
	case NameKey:
		if v, ok := value.(string); ok {
			t.name = &v
			return nil
		}
		return fmt.Errorf(`invalid value for %s key: %T`, NameKey, value)
	case NicknameKey:
		if v, ok := value.(string); ok {
			t.nickname = &v
			return nil
		}
		return fmt.Errorf(`invalid value for %s key: %T`, NicknameKey, value)
	case NotBeforeKey:
		var acceptor types.NumericDate
		if err := acceptor.Accept(value); err != nil {
			return fmt.Errorf(`invalid value for %s key: %w`, NotBeforeKey, err)
		}
		t.notBefore = &acceptor
		return nil
	case PhoneNumberKey:
		if v, ok := value.(string); ok {
			t.phoneNumber = &v
			return nil
		}
		return fmt.Errorf(`invalid value for %s key: %T`, PhoneNumberKey, value)
	case PhoneNumberVerifiedKey:
		if v, ok := value.(bool); ok {
			t.phoneNumberVerified = &v
			return nil
		}
		return fmt.Errorf(`invalid value for %s key: %T`, PhoneNumberVerifiedKey, value)
	case PictureKey:
		if v, ok := value.(string); ok {
			t.picture = &v
			return nil
		}
		return fmt.Errorf(`invalid value for %s key: %T`, PictureKey, value)
	case PreferredUsernameKey:
		if v, ok := value.(string); ok {
			t.preferredUsername = &v
			return nil
		}
		return fmt.Errorf(`invalid value for %s key: %T`, PreferredUsernameKey, value)
	case ProfileKey:
		if v, ok := value.(string); ok {
			t.profile = &v
			return nil
		}
		return fmt.Errorf(`invalid value for %s key: %T`, ProfileKey, value)
	case SubjectKey:
		if v, ok := value.(string); ok {
			t.subject = &v
			return nil
		}
		return fmt.Errorf(`invalid value for %s key: %T`, SubjectKey, value)
	case UpdatedAtKey:
		var acceptor types.NumericDate
		if err := acceptor.Accept(value); err != nil {
			return fmt.Errorf(`invalid value for %s key: %w`, UpdatedAtKey, err)
		}
		t.updatedAt = &acceptor
		return nil
	case WebsiteKey:
		if v, ok := value.(string); ok {
			t.website = &v
			return nil
		}
		return fmt.Errorf(`invalid value for %s key: %T`, WebsiteKey, value)
	case ZoneinfoKey:
		if v, ok := value.(string); ok {
			t.zoneinfo = &v
			return nil
		}
		return fmt.Errorf(`invalid value for %s key: %T`, ZoneinfoKey, value)
	default:
		if t.privateClaims == nil {
			t.privateClaims = map[string]any{}
		}
		t.privateClaims[name] = value
	}
	return nil
}

func (t *stdToken) Address() (*AddressClaim, bool) {
	t.mu.RLock()
	defer t.mu.RUnlock()
	if t.address != nil {
		return t.address, true
	}
	return nil, false
}

func (t *stdToken) Audience() ([]string, bool) {
	t.mu.RLock()
	defer t.mu.RUnlock()
	if t.audience != nil {
		return t.audience.Get(), true
	}
	return nil, false
}

func (t *stdToken) Birthdate() (*BirthdateClaim, bool) {
	t.mu.RLock()
	defer t.mu.RUnlock()
	if t.birthdate != nil {
		return t.birthdate, true
	}
	return nil, false
}

func (t *stdToken) Email() (string, bool) {
	t.mu.RLock()
	defer t.mu.RUnlock()
	if t.email != nil {
		return *(t.email), true
	}
	return "", false
}

func (t *stdToken) EmailVerified() (bool, bool) {
	t.mu.RLock()
	defer t.mu.RUnlock()
	if t.emailVerified != nil {
		return *(t.emailVerified), true
	}
	return false, false
}

func (t *stdToken) Expiration() (time.Time, bool) {
	t.mu.RLock()
	defer t.mu.RUnlock()
	if t.expiration != nil {
		return t.expiration.Get(), true
	}
	return time.Time{}, false
}

func (t *stdToken) FamilyName() (string, bool) {
	t.mu.RLock()
	defer t.mu.RUnlock()
	if t.familyName != nil {
		return *(t.familyName), true
	}
	return "", false
}

func (t *stdToken) Gender() (string, bool) {
	t.mu.RLock()
	defer t.mu.RUnlock()
	if t.gender != nil {
		return *(t.gender), true
	}
	return "", false
}

func (t *stdToken) GivenName() (string, bool) {
	t.mu.RLock()
	defer t.mu.RUnlock()
	if t.givenName != nil {
		return *(t.givenName), true
	}
	return "", false
}

func (t *stdToken) IssuedAt() (time.Time, bool) {
	t.mu.RLock()
	defer t.mu.RUnlock()
	if t.issuedAt != nil {
		return t.issuedAt.Get(), true
	}
	return time.Time{}, false
}

func (t *stdToken) Issuer() (string, bool) {
	t.mu.RLock()
	defer t.mu.RUnlock()
	if t.issuer != nil {
		return *(t.issuer), true
	}
	return "", false
}

func (t *stdToken) JwtID() (string, bool) {
	t.mu.RLock()
	defer t.mu.RUnlock()
	if t.jwtID != nil {
		return *(t.jwtID), true
	}
	return "", false
}

func (t *stdToken) Locale() (string, bool) {
	t.mu.RLock()
	defer t.mu.RUnlock()
	if t.locale != nil {
		return *(t.locale), true
	}
	return "", false
}

func (t *stdToken) MiddleName() (string, bool) {
	t.mu.RLock()
	defer t.mu.RUnlock()
	if t.middleName != nil {
		return *(t.middleName), true
	}
	return "", false
}

func (t *stdToken) Name() (string, bool) {
	t.mu.RLock()
	defer t.mu.RUnlock()
	if t.name != nil {
		return *(t.name), true
	}
	return "", false
}

func (t *stdToken) Nickname() (string, bool) {
	t.mu.RLock()
	defer t.mu.RUnlock()
	if t.nickname != nil {
		return *(t.nickname), true
	}
	return "", false
}

func (t *stdToken) NotBefore() (time.Time, bool) {
	t.mu.RLock()
	defer t.mu.RUnlock()
	if t.notBefore != nil {
		return t.notBefore.Get(), true
	}
	return time.Time{}, false
}

func (t *stdToken) PhoneNumber() (string, bool) {
	t.mu.RLock()
	defer t.mu.RUnlock()
	if t.phoneNumber != nil {
		return *(t.phoneNumber), true
	}
	return "", false
}

func (t *stdToken) PhoneNumberVerified() (bool, bool) {
	t.mu.RLock()
	defer t.mu.RUnlock()
	if t.phoneNumberVerified != nil {
		return *(t.phoneNumberVerified), true
	}
	return false, false
}

func (t *stdToken) Picture() (string, bool) {
	t.mu.RLock()
	defer t.mu.RUnlock()
	if t.picture != nil {
		return *(t.picture), true
	}
	return "", false
}

func (t *stdToken) PreferredUsername() (string, bool) {
	t.mu.RLock()
	defer t.mu.RUnlock()
	if t.preferredUsername != nil {
		return *(t.preferredUsername), true
	}
	return "", false
}

func (t *stdToken) Profile() (string, bool) {
	t.mu.RLock()
	defer t.mu.RUnlock()
	if t.profile != nil {
		return *(t.profile), true
	}
	return "", false
}

func (t *stdToken) Subject() (string, bool) {
	t.mu.RLock()
	defer t.mu.RUnlock()
	if t.subject != nil {
		return *(t.subject), true
	}
	return "", false
}

func (t *stdToken) UpdatedAt() (time.Time, bool) {
	t.mu.RLock()
	defer t.mu.RUnlock()
	if t.updatedAt != nil {
		return t.updatedAt.Get(), true
	}
	return time.Time{}, false
}

func (t *stdToken) Website() (string, bool) {
	t.mu.RLock()
	defer t.mu.RUnlock()
	if t.website != nil {
		return *(t.website), true
	}
	return "", false
}

func (t *stdToken) Zoneinfo() (string, bool) {
	t.mu.RLock()
	defer t.mu.RUnlock()
	if t.zoneinfo != nil {
		return *(t.zoneinfo), true
	}
	return "", false
}

func (t *stdToken) PrivateClaims() map[string]any {
	t.mu.RLock()
	defer t.mu.RUnlock()
	return t.privateClaims
}

func (t *stdToken) UnmarshalJSON(buf []byte) error {
	t.mu.Lock()
	defer t.mu.Unlock()
	t.address = nil
	t.audience = nil
	t.birthdate = nil
	t.email = nil
	t.emailVerified = nil
	t.expiration = nil
	t.familyName = nil
	t.gender = nil
	t.givenName = nil
	t.issuedAt = nil
	t.issuer = nil
	t.jwtID = nil
	t.locale = nil
	t.middleName = nil
	t.name = nil
	t.nickname = nil
	t.notBefore = nil
	t.phoneNumber = nil
	t.phoneNumberVerified = nil
	t.picture = nil
	t.preferredUsername = nil
	t.profile = nil
	t.subject = nil
	t.updatedAt = nil
	t.website = nil
	t.zoneinfo = nil
	dec := json.NewDecoder(bytes.NewReader(buf))
LOOP:
	for {
		tok, err := dec.Token()
		if err != nil {
			return fmt.Errorf(`error reading token: %w`, err)
		}
		switch tok := tok.(type) {
		case json.Delim:
			// Assuming we're doing everything correctly, we should ONLY
			// get either tokens.OpenCurlyBracket or tokens.CloseCurlyBracket here.
			if tok == tokens.CloseCurlyBracket { // End of object
				break LOOP
			} else if tok != tokens.OpenCurlyBracket {
				return fmt.Errorf(`expected '%c', but got '%c'`, tokens.OpenCurlyBracket, tok)
			}
		case string: // Objects can only have string keys
			switch tok {
			case AddressKey:
				var decoded AddressClaim
				if err := dec.Decode(&decoded); err != nil {
					return fmt.Errorf(`failed to decode value for key %s: %w`, AddressKey, err)
				}
				t.address = &decoded
			case AudienceKey:
				var decoded types.StringList
				if err := dec.Decode(&decoded); err != nil {
					return fmt.Errorf(`failed to decode value for key %s: %w`, AudienceKey, err)
				}
				t.audience = decoded
			case BirthdateKey:
				var decoded BirthdateClaim
				if err := dec.Decode(&decoded); err != nil {
					return fmt.Errorf(`failed to decode value for key %s: %w`, BirthdateKey, err)
				}
				t.birthdate = &decoded
			case EmailKey:
				if err := json.AssignNextStringToken(&t.email, dec); err != nil {
					return fmt.Errorf(`failed to decode value for key %s: %w`, EmailKey, err)
				}
			case EmailVerifiedKey:
				var decoded bool
				if err := dec.Decode(&decoded); err != nil {
					return fmt.Errorf(`failed to decode value for key %s: %w`, EmailVerifiedKey, err)
				}
				t.emailVerified = &decoded
			case ExpirationKey:
				var decoded types.NumericDate
				if err := dec.Decode(&decoded); err != nil {
					return fmt.Errorf(`failed to decode value for key %s: %w`, ExpirationKey, err)
				}
				t.expiration = &decoded
			case FamilyNameKey:
				if err := json.AssignNextStringToken(&t.familyName, dec); err != nil {
					return fmt.Errorf(`failed to decode value for key %s: %w`, FamilyNameKey, err)
				}
			case GenderKey:
				if err := json.AssignNextStringToken(&t.gender, dec); err != nil {
					return fmt.Errorf(`failed to decode value for key %s: %w`, GenderKey, err)
				}
			case GivenNameKey:
				if err := json.AssignNextStringToken(&t.givenName, dec); err != nil {
					return fmt.Errorf(`failed to decode value for key %s: %w`, GivenNameKey, err)
				}
			case IssuedAtKey:
				var decoded types.NumericDate
				if err := dec.Decode(&decoded); err != nil {
					return fmt.Errorf(`failed to decode value for key %s: %w`, IssuedAtKey, err)
				}
				t.issuedAt = &decoded
			case IssuerKey:
				if err := json.AssignNextStringToken(&t.issuer, dec); err != nil {
					return fmt.Errorf(`failed to decode value for key %s: %w`, IssuerKey, err)
				}
			case JwtIDKey:
				if err := json.AssignNextStringToken(&t.jwtID, dec); err != nil {
					return fmt.Errorf(`failed to decode value for key %s: %w`, JwtIDKey, err)
				}
			case LocaleKey:
				if err := json.AssignNextStringToken(&t.locale, dec); err != nil {
					return fmt.Errorf(`failed to decode value for key %s: %w`, LocaleKey, err)
				}
			case MiddleNameKey:
				if err := json.AssignNextStringToken(&t.middleName, dec); err != nil {
					return fmt.Errorf(`failed to decode value for key %s: %w`, MiddleNameKey, err)
				}
			case NameKey:
				if err := json.AssignNextStringToken(&t.name, dec); err != nil {
					return fmt.Errorf(`failed to decode value for key %s: %w`, NameKey, err)
				}
			case NicknameKey:
				if err := json.AssignNextStringToken(&t.nickname, dec); err != nil {
					return fmt.Errorf(`failed to decode value for key %s: %w`, NicknameKey, err)
				}
			case NotBeforeKey:
				var decoded types.NumericDate
				if err := dec.Decode(&decoded); err != nil {
					return fmt.Errorf(`failed to decode value for key %s: %w`, NotBeforeKey, err)
				}
				t.notBefore = &decoded
			case PhoneNumberKey:
				if err := json.AssignNextStringToken(&t.phoneNumber, dec); err != nil {
					return fmt.Errorf(`failed to decode value for key %s: %w`, PhoneNumberKey, err)
				}
			case PhoneNumberVerifiedKey:
				var decoded bool
				if err := dec.Decode(&decoded); err != nil {
					return fmt.Errorf(`failed to decode value for key %s: %w`, PhoneNumberVerifiedKey, err)
				}
				t.phoneNumberVerified = &decoded
			case PictureKey:
				if err := json.AssignNextStringToken(&t.picture, dec); err != nil {
					return fmt.Errorf(`failed to decode value for key %s: %w`, PictureKey, err)
				}
			case PreferredUsernameKey:
				if err := json.AssignNextStringToken(&t.preferredUsername, dec); err != nil {
					return fmt.Errorf(`failed to decode value for key %s: %w`, PreferredUsernameKey, err)
				}
			case ProfileKey:
				if err := json.AssignNextStringToken(&t.profile, dec); err != nil {
					return fmt.Errorf(`failed to decode value for key %s: %w`, ProfileKey, err)
				}
			case SubjectKey:
				if err := json.AssignNextStringToken(&t.subject, dec); err != nil {
					return fmt.Errorf(`failed to decode value for key %s: %w`, SubjectKey, err)
				}
			case UpdatedAtKey:
				var decoded types.NumericDate
				if err := dec.Decode(&decoded); err != nil {
					return fmt.Errorf(`failed to decode value for key %s: %w`, UpdatedAtKey, err)
				}
				t.updatedAt = &decoded
			case WebsiteKey:
				if err := json.AssignNextStringToken(&t.website, dec); err != nil {
					return fmt.Errorf(`failed to decode value for key %s: %w`, WebsiteKey, err)
				}
			case ZoneinfoKey:
				if err := json.AssignNextStringToken(&t.zoneinfo, dec); err != nil {
					return fmt.Errorf(`failed to decode value for key %s: %w`, ZoneinfoKey, err)
				}
			default:
				if dc := t.dc; dc != nil {
					if localReg := dc.Registry(); localReg != nil {
						decoded, err := localReg.Decode(dec, tok)
						if err == nil {
							t.setNoLock(tok, decoded)
							continue
						}
					}
				}
				decoded, err := registry.Decode(dec, tok)
				if err == nil {
					t.setNoLock(tok, decoded)
					continue
				}
				return fmt.Errorf(`could not decode field %s: %w`, tok, err)
			}
		default:
			return fmt.Errorf(`invalid token %T`, tok)
		}
	}
	return nil
}

func (t *stdToken) Keys() []string {
	t.mu.RLock()
	defer t.mu.RUnlock()
	keys := make([]string, 0, 26+len(t.privateClaims))
	if t.address != nil {
		keys = append(keys, AddressKey)
	}
	if t.audience != nil {
		keys = append(keys, AudienceKey)
	}
	if t.birthdate != nil {
		keys = append(keys, BirthdateKey)
	}
	if t.email != nil {
		keys = append(keys, EmailKey)
	}
	if t.emailVerified != nil {
		keys = append(keys, EmailVerifiedKey)
	}
	if t.expiration != nil {
		keys = append(keys, ExpirationKey)
	}
	if t.familyName != nil {
		keys = append(keys, FamilyNameKey)
	}
	if t.gender != nil {
		keys = append(keys, GenderKey)
	}
	if t.givenName != nil {
		keys = append(keys, GivenNameKey)
	}
	if t.issuedAt != nil {
		keys = append(keys, IssuedAtKey)
	}
	if t.issuer != nil {
		keys = append(keys, IssuerKey)
	}
	if t.jwtID != nil {
		keys = append(keys, JwtIDKey)
	}
	if t.locale != nil {
		keys = append(keys, LocaleKey)
	}
	if t.middleName != nil {
		keys = append(keys, MiddleNameKey)
	}
	if t.name != nil {
		keys = append(keys, NameKey)
	}
	if t.nickname != nil {
		keys = append(keys, NicknameKey)
	}
	if t.notBefore != nil {
		keys = append(keys, NotBeforeKey)
	}
	if t.phoneNumber != nil {
		keys = append(keys, PhoneNumberKey)
	}
	if t.phoneNumberVerified != nil {
		keys = append(keys, PhoneNumberVerifiedKey)
	}
	if t.picture != nil {
		keys = append(keys, PictureKey)
	}
	if t.preferredUsername != nil {
		keys = append(keys, PreferredUsernameKey)
	}
	if t.profile != nil {
		keys = append(keys, ProfileKey)
	}
	if t.subject != nil {
		keys = append(keys, SubjectKey)
	}
	if t.updatedAt != nil {
		keys = append(keys, UpdatedAtKey)
	}
	if t.website != nil {
		keys = append(keys, WebsiteKey)
	}
	if t.zoneinfo != nil {
		keys = append(keys, ZoneinfoKey)
	}
	for k := range t.privateClaims {
		keys = append(keys, k)
	}
	return keys
}

type claimPair struct {
	Name  string
	Value any
}

var claimPairPool = sync.Pool{
	New: func() any {
		return make([]claimPair, 0, 26)
	},
}

func getClaimPairList() []claimPair {
	return claimPairPool.Get().([]claimPair)
}

func putClaimPairList(list []claimPair) {
	list = list[:0]
	claimPairPool.Put(list)
}

// makePairs creates a list of claimPair objects that are sorted by
// their key names. The key names are always their JSON names, and
// the values are already JSON encoded.
// Because makePairs needs to allocate a slice, it _slows_ down
// marshaling of the token to JSON. The upside is that it allows us to
// marshal the token keys in a deterministic order.
// Do we really need it...? Well, technically we don't, but it's so
// much nicer to have this to make the example tests actually work
// deterministically. Also if for whatever reason this becomes a
// performance issue, we can always/ add a flag to use a more _optimized_ code path.
//
// The caller is responsible to call putClaimPairList() to return the
// allocated slice back to the pool.

func (t *stdToken) makePairs() ([]claimPair, error) {
	pairs := getClaimPairList()
	if t.address != nil {
		buf, err := json.Marshal(*(t.address))
		if err != nil {
			return nil, fmt.Errorf(`failed to encode field "address": %w`, err)
		}
		pairs = append(pairs, claimPair{Name: AddressKey, Value: buf})
	}
	if t.audience != nil {
		buf, err := json.MarshalAudience(t.audience, t.options.IsEnabled(jwt.FlattenAudience))
		if err != nil {
			return nil, fmt.Errorf(`failed to encode "aud": %w`, err)
		}
		pairs = append(pairs, claimPair{Name: AudienceKey, Value: buf})
	}
	if t.birthdate != nil {
		buf, err := json.Marshal(*(t.birthdate))
		if err != nil {
			return nil, fmt.Errorf(`failed to encode field "birthdate": %w`, err)
		}
		pairs = append(pairs, claimPair{Name: BirthdateKey, Value: buf})
	}
	if t.email != nil {
		buf, err := json.Marshal(*(t.email))
		if err != nil {
			return nil, fmt.Errorf(`failed to encode field "email": %w`, err)
		}
		pairs = append(pairs, claimPair{Name: EmailKey, Value: buf})
	}
	if t.emailVerified != nil {
		buf, err := json.Marshal(*(t.emailVerified))
		if err != nil {
			return nil, fmt.Errorf(`failed to encode field "email_verified": %w`, err)
		}
		pairs = append(pairs, claimPair{Name: EmailVerifiedKey, Value: buf})
	}
	if t.expiration != nil {
		buf, err := json.Marshal(t.expiration.Unix())
		if err != nil {
			return nil, fmt.Errorf(`failed to encode "exp": %w`, err)
		}
		pairs = append(pairs, claimPair{Name: ExpirationKey, Value: buf})
	}
	if t.familyName != nil {
		buf, err := json.Marshal(*(t.familyName))
		if err != nil {
			return nil, fmt.Errorf(`failed to encode field "family_name": %w`, err)
		}
		pairs = append(pairs, claimPair{Name: FamilyNameKey, Value: buf})
	}
	if t.gender != nil {
		buf, err := json.Marshal(*(t.gender))
		if err != nil {
			return nil, fmt.Errorf(`failed to encode field "gender": %w`, err)
		}
		pairs = append(pairs, claimPair{Name: GenderKey, Value: buf})
	}
	if t.givenName != nil {
		buf, err := json.Marshal(*(t.givenName))
		if err != nil {
			return nil, fmt.Errorf(`failed to encode field "given_name": %w`, err)
		}
		pairs = append(pairs, claimPair{Name: GivenNameKey, Value: buf})
	}
	if t.issuedAt != nil {
		buf, err := json.Marshal(t.issuedAt.Unix())
		if err != nil {
			return nil, fmt.Errorf(`failed to encode "iat": %w`, err)
		}
		pairs = append(pairs, claimPair{Name: IssuedAtKey, Value: buf})
	}
	if t.issuer != nil {
		buf, err := json.Marshal(*(t.issuer))
		if err != nil {
			return nil, fmt.Errorf(`failed to encode field "iss": %w`, err)
		}
		pairs = append(pairs, claimPair{Name: IssuerKey, Value: buf})
	}
	if t.jwtID != nil {
		buf, err := json.Marshal(*(t.jwtID))
		if err != nil {
			return nil, fmt.Errorf(`failed to encode field "jti": %w`, err)
		}
		pairs = append(pairs, claimPair{Name: JwtIDKey, Value: buf})
	}
	if t.locale != nil {
		buf, err := json.Marshal(*(t.locale))
		if err != nil {
			return nil, fmt.Errorf(`failed to encode field "locale": %w`, err)
		}
		pairs = append(pairs, claimPair{Name: LocaleKey, Value: buf})
	}
	if t.middleName != nil {
		buf, err := json.Marshal(*(t.middleName))
		if err != nil {
			return nil, fmt.Errorf(`failed to encode field "middle_name": %w`, err)
		}
		pairs = append(pairs, claimPair{Name: MiddleNameKey, Value: buf})
	}
	if t.name != nil {
		buf, err := json.Marshal(*(t.name))
		if err != nil {
			return nil, fmt.Errorf(`failed to encode field "name": %w`, err)
		}
		pairs = append(pairs, claimPair{Name: NameKey, Value: buf})
	}
	if t.nickname != nil {
		buf, err := json.Marshal(*(t.nickname))
		if err != nil {
			return nil, fmt.Errorf(`failed to encode field "nickname": %w`, err)
		}
		pairs = append(pairs, claimPair{Name: NicknameKey, Value: buf})
	}
	if t.notBefore != nil {
		buf, err := json.Marshal(t.notBefore.Unix())
		if err != nil {
			return nil, fmt.Errorf(`failed to encode "nbf": %w`, err)
		}
		pairs = append(pairs, claimPair{Name: NotBeforeKey, Value: buf})
	}
	if t.phoneNumber != nil {
		buf, err := json.Marshal(*(t.phoneNumber))
		if err != nil {
			return nil, fmt.Errorf(`failed to encode field "phone_number": %w`, err)
		}
		pairs = append(pairs, claimPair{Name: PhoneNumberKey, Value: buf})
	}
	if t.phoneNumberVerified != nil {
		buf, err := json.Marshal(*(t.phoneNumberVerified))
		if err != nil {
			return nil, fmt.Errorf(`failed to encode field "phone_number_verified": %w`, err)
		}
		pairs = append(pairs, claimPair{Name: PhoneNumberVerifiedKey, Value: buf})
	}
	if t.picture != nil {
		buf, err := json.Marshal(*(t.picture))
		if err != nil {
			return nil, fmt.Errorf(`failed to encode field "picture": %w`, err)
		}
		pairs = append(pairs, claimPair{Name: PictureKey, Value: buf})
	}
	if t.preferredUsername != nil {
		buf, err := json.Marshal(*(t.preferredUsername))
		if err != nil {
			return nil, fmt.Errorf(`failed to encode field "preferred_username": %w`, err)
		}
		pairs = append(pairs, claimPair{Name: PreferredUsernameKey, Value: buf})
	}
	if t.profile != nil {
		buf, err := json.Marshal(*(t.profile))
		if err != nil {
			return nil, fmt.Errorf(`failed to encode field "profile": %w`, err)
		}
		pairs = append(pairs, claimPair{Name: ProfileKey, Value: buf})
	}
	if t.subject != nil {
		buf, err := json.Marshal(*(t.subject))
		if err != nil {
			return nil, fmt.Errorf(`failed to encode field "sub": %w`, err)
		}
		pairs = append(pairs, claimPair{Name: SubjectKey, Value: buf})
	}
	if t.updatedAt != nil {
		buf, err := json.Marshal(t.updatedAt.Unix())
		if err != nil {
			return nil, fmt.Errorf(`failed to encode "updated_at": %w`, err)
		}
		pairs = append(pairs, claimPair{Name: UpdatedAtKey, Value: buf})
	}
	if t.website != nil {
		buf, err := json.Marshal(*(t.website))
		if err != nil {
			return nil, fmt.Errorf(`failed to encode field "website": %w`, err)
		}
		pairs = append(pairs, claimPair{Name: WebsiteKey, Value: buf})
	}
	if t.zoneinfo != nil {
		buf, err := json.Marshal(*(t.zoneinfo))
		if err != nil {
			return nil, fmt.Errorf(`failed to encode field "zoneinfo": %w`, err)
		}
		pairs = append(pairs, claimPair{Name: ZoneinfoKey, Value: buf})
	}
	for k, v := range t.privateClaims {
		buf, err := json.Marshal(v)
		if err != nil {
			return nil, fmt.Errorf(`failed to encode field %q: %w`, k, err)
		}
		pairs = append(pairs, claimPair{Name: k, Value: buf})
	}

	sort.Slice(pairs, func(i, j int) bool {
		return pairs[i].Name < pairs[j].Name
	})

	return pairs, nil
}

func (t stdToken) MarshalJSON() ([]byte, error) {
	buf := pool.BytesBuffer().Get()
	defer pool.BytesBuffer().Put(buf)
	pairs, err := t.makePairs()
	if err != nil {
		return nil, fmt.Errorf(`failed to make pairs: %w`, err)
	}
	buf.WriteByte(tokens.OpenCurlyBracket)

	for i, pair := range pairs {
		if i > 0 {
			buf.WriteByte(tokens.Comma)
		}
		fmt.Fprintf(buf, "%q: %s", pair.Name, pair.Value)
	}
	buf.WriteByte(tokens.CloseCurlyBracket)
	ret := make([]byte, buf.Len())
	copy(ret, buf.Bytes())
	putClaimPairList(pairs)
	return ret, nil
}
