.
-//
-// Use of this source code is governed by an MIT-style
-// license that can be found in the LICENSE file.
-
-package jwalterweatherman
-
-import (
- "fmt"
- "io"
- "io/ioutil"
- "log"
-)
-
-type Threshold int
-
-func (t Threshold) String() string {
- return prefixes[t]
-}
-
-const (
- LevelTrace Threshold = iota
- LevelDebug
- LevelInfo
- LevelWarn
- LevelError
- LevelCritical
- LevelFatal
-)
-
-var prefixes map[Threshold]string = map[Threshold]string{
- LevelTrace: "TRACE",
- LevelDebug: "DEBUG",
- LevelInfo: "INFO",
- LevelWarn: "WARN",
- LevelError: "ERROR",
- LevelCritical: "CRITICAL",
- LevelFatal: "FATAL",
-}
-
-// Notepad is where you leave a note!
-type Notepad struct {
- TRACE *log.Logger
- DEBUG *log.Logger
- INFO *log.Logger
- WARN *log.Logger
- ERROR *log.Logger
- CRITICAL *log.Logger
- FATAL *log.Logger
-
- LOG *log.Logger
- FEEDBACK *Feedback
-
- loggers [7]**log.Logger
- logHandle io.Writer
- outHandle io.Writer
- logThreshold Threshold
- stdoutThreshold Threshold
- prefix string
- flags int
-
- logListeners []LogListener
-}
-
-// A LogListener can ble supplied to a Notepad to listen on log writes for a given
-// threshold. This can be used to capture log events in unit tests and similar.
-// Note that this function will be invoked once for each log threshold. If
-// the given threshold is not of interest to you, return nil.
-// Note that these listeners will receive log events for a given threshold, even
-// if the current configuration says not to log it. That way you can count ERRORs even
-// if you don't print them to the console.
-type LogListener func(t Threshold) io.Writer
-
-// NewNotepad creates a new Notepad.
-func NewNotepad(
- outThreshold Threshold,
- logThreshold Threshold,
- outHandle, logHandle io.Writer,
- prefix string, flags int,
- logListeners ...LogListener,
-) *Notepad {
-
- n := &Notepad{logListeners: logListeners}
-
- n.loggers = [7]**log.Logger{&n.TRACE, &n.DEBUG, &n.INFO, &n.WARN, &n.ERROR, &n.CRITICAL, &n.FATAL}
- n.outHandle = outHandle
- n.logHandle = logHandle
- n.stdoutThreshold = outThreshold
- n.logThreshold = logThreshold
-
- if len(prefix) != 0 {
- n.prefix = "[" + prefix + "] "
- } else {
- n.prefix = ""
- }
-
- n.flags = flags
-
- n.LOG = log.New(n.logHandle,
- "LOG: ",
- n.flags)
- n.FEEDBACK = &Feedback{out: log.New(outHandle, "", 0), log: n.LOG}
-
- n.init()
- return n
-}
-
-// init creates the loggers for each level depending on the notepad thresholds.
-func (n *Notepad) init() {
- logAndOut := io.MultiWriter(n.outHandle, n.logHandle)
-
- for t, logger := range n.loggers {
- threshold := Threshold(t)
- prefix := n.prefix + threshold.String() + " "
-
- switch {
- case threshold >= n.logThreshold && threshold >= n.stdoutThreshold:
- *logger = log.New(n.createLogWriters(threshold, logAndOut), prefix, n.flags)
-
- case threshold >= n.logThreshold:
- *logger = log.New(n.createLogWriters(threshold, n.logHandle), prefix, n.flags)
-
- case threshold >= n.stdoutThreshold:
- *logger = log.New(n.createLogWriters(threshold, n.outHandle), prefix, n.flags)
-
- default:
- *logger = log.New(n.createLogWriters(threshold, ioutil.Discard), prefix, n.flags)
- }
- }
-}
-
-func (n *Notepad) createLogWriters(t Threshold, handle io.Writer) io.Writer {
- if len(n.logListeners) == 0 {
- return handle
- }
- writers := []io.Writer{handle}
- for _, l := range n.logListeners {
- w := l(t)
- if w != nil {
- writers = append(writers, w)
- }
- }
-
- if len(writers) == 1 {
- return handle
- }
-
- return io.MultiWriter(writers...)
-}
-
-// SetLogThreshold changes the threshold above which messages are written to the
-// log file.
-func (n *Notepad) SetLogThreshold(threshold Threshold) {
- n.logThreshold = threshold
- n.init()
-}
-
-// SetLogOutput changes the file where log messages are written.
-func (n *Notepad) SetLogOutput(handle io.Writer) {
- n.logHandle = handle
- n.init()
-}
-
-// GetStdoutThreshold returns the defined Treshold for the log logger.
-func (n *Notepad) GetLogThreshold() Threshold {
- return n.logThreshold
-}
-
-// SetStdoutThreshold changes the threshold above which messages are written to the
-// standard output.
-func (n *Notepad) SetStdoutThreshold(threshold Threshold) {
- n.stdoutThreshold = threshold
- n.init()
-}
-
-// GetStdoutThreshold returns the Treshold for the stdout logger.
-func (n *Notepad) GetStdoutThreshold() Threshold {
- return n.stdoutThreshold
-}
-
-// SetPrefix changes the prefix used by the notepad. Prefixes are displayed between
-// brackets at the beginning of the line. An empty prefix won't be displayed at all.
-func (n *Notepad) SetPrefix(prefix string) {
- if len(prefix) != 0 {
- n.prefix = "[" + prefix + "] "
- } else {
- n.prefix = ""
- }
- n.init()
-}
-
-// SetFlags choose which flags the logger will display (after prefix and message
-// level). See the package log for more informations on this.
-func (n *Notepad) SetFlags(flags int) {
- n.flags = flags
- n.init()
-}
-
-// Feedback writes plainly to the outHandle while
-// logging with the standard extra information (date, file, etc).
-type Feedback struct {
- out *log.Logger
- log *log.Logger
-}
-
-func (fb *Feedback) Println(v ...interface{}) {
- fb.output(fmt.Sprintln(v...))
-}
-
-func (fb *Feedback) Printf(format string, v ...interface{}) {
- fb.output(fmt.Sprintf(format, v...))
-}
-
-func (fb *Feedback) Print(v ...interface{}) {
- fb.output(fmt.Sprint(v...))
-}
-
-func (fb *Feedback) output(s string) {
- if fb.out != nil {
- fb.out.Output(2, s)
- }
- if fb.log != nil {
- fb.log.Output(2, s)
- }
-}
diff --git a/vendor/github.com/spf13/viper/.editorconfig b/vendor/github.com/spf13/viper/.editorconfig
index 6d0b6d356..1f664d13a 100644
--- a/vendor/github.com/spf13/viper/.editorconfig
+++ b/vendor/github.com/spf13/viper/.editorconfig
@@ -13,3 +13,6 @@ indent_style = tab
[{Makefile,*.mk}]
indent_style = tab
+
+[*.nix]
+indent_size = 2
diff --git a/vendor/github.com/spf13/viper/.gitignore b/vendor/github.com/spf13/viper/.gitignore
index 896250839..f1bbd4280 100644
--- a/vendor/github.com/spf13/viper/.gitignore
+++ b/vendor/github.com/spf13/viper/.gitignore
@@ -1,4 +1,7 @@
+/.devenv/
+/.direnv/
/.idea/
+/.pre-commit-config.yaml
/bin/
/build/
/var/
diff --git a/vendor/github.com/spf13/viper/.golangci.yaml b/vendor/github.com/spf13/viper/.golangci.yaml
index acd9eebac..1faeae42c 100644
--- a/vendor/github.com/spf13/viper/.golangci.yaml
+++ b/vendor/github.com/spf13/viper/.golangci.yaml
@@ -7,6 +7,16 @@ linters-settings:
- standard
- default
- prefix(github.com/spf13/viper)
+ gocritic:
+ # Enable multiple checks by tags. See "Tags" section in https://github.com/go-critic/go-critic#usage.
+ enabled-tags:
+ - diagnostic
+ - experimental
+ - opinionated
+ - style
+ disabled-checks:
+ - importShadow
+ - unnamedResult
golint:
min-confidence: 0
goimports:
@@ -22,6 +32,8 @@ linters:
- exhaustive
- exportloopref
- gci
+ - gocritic
+ - godot
- gofmt
- gofumpt
- goimports
@@ -62,9 +74,7 @@ linters:
# - gochecknoinits
# - gocognit
# - goconst
- # - gocritic
# - gocyclo
- # - godot
# - gosec
# - gosimple
# - ifshort
diff --git a/vendor/github.com/spf13/viper/.yamlignore b/vendor/github.com/spf13/viper/.yamlignore
new file mode 100644
index 000000000..c04c4dead
--- /dev/null
+++ b/vendor/github.com/spf13/viper/.yamlignore
@@ -0,0 +1,2 @@
+# TODO: FIXME
+/.github/
diff --git a/vendor/github.com/spf13/viper/.yamllint.yaml b/vendor/github.com/spf13/viper/.yamllint.yaml
new file mode 100644
index 000000000..bac19ce18
--- /dev/null
+++ b/vendor/github.com/spf13/viper/.yamllint.yaml
@@ -0,0 +1,6 @@
+ignore-from-file: [.gitignore, .yamlignore]
+
+extends: default
+
+rules:
+ line-length: disable
diff --git a/vendor/github.com/spf13/viper/Makefile b/vendor/github.com/spf13/viper/Makefile
index e8d3baaa8..a77b9c81c 100644
--- a/vendor/github.com/spf13/viper/Makefile
+++ b/vendor/github.com/spf13/viper/Makefile
@@ -16,7 +16,7 @@ endif
# Dependency versions
GOTESTSUM_VERSION = 1.9.0
-GOLANGCI_VERSION = 1.52.2
+GOLANGCI_VERSION = 1.53.3
# Add the ability to override some variables
# Use with care
@@ -29,11 +29,6 @@ clear: ## Clear the working area and the project
.PHONY: check
check: test lint ## Run tests and linters
-bin/gotestsum: bin/gotestsum-${GOTESTSUM_VERSION}
- @ln -sf gotestsum-${GOTESTSUM_VERSION} bin/gotestsum
-bin/gotestsum-${GOTESTSUM_VERSION}:
- @mkdir -p bin
- curl -L https://github.com/gotestyourself/gotestsum/releases/download/v${GOTESTSUM_VERSION}/gotestsum_${GOTESTSUM_VERSION}_${OS}_amd64.tar.gz | tar -zOxf - gotestsum > ./bin/gotestsum-${GOTESTSUM_VERSION} && chmod +x ./bin/gotestsum-${GOTESTSUM_VERSION}
TEST_PKGS ?= ./...
.PHONY: test
@@ -44,20 +39,36 @@ test: bin/gotestsum ## Run tests
@mkdir -p ${BUILD_DIR}
bin/gotestsum --no-summary=skipped --junitfile ${BUILD_DIR}/coverage.xml --format ${TEST_FORMAT} -- -race -coverprofile=${BUILD_DIR}/coverage.txt -covermode=atomic $(filter-out -v,${GOARGS}) $(if ${TEST_PKGS},${TEST_PKGS},./...)
-bin/golangci-lint: bin/golangci-lint-${GOLANGCI_VERSION}
- @ln -sf golangci-lint-${GOLANGCI_VERSION} bin/golangci-lint
-bin/golangci-lint-${GOLANGCI_VERSION}:
- @mkdir -p bin
- curl -sfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | bash -s -- -b ./bin/ v${GOLANGCI_VERSION}
- @mv bin/golangci-lint "$@"
-
.PHONY: lint
-lint: bin/golangci-lint ## Run linter
- bin/golangci-lint run
+lint: lint-go lint-yaml
+lint: ## Run linters
-.PHONY: fix
-fix: bin/golangci-lint ## Fix lint violations
- bin/golangci-lint run --fix
+.PHONY: lint-go
+lint-go:
+ golangci-lint run $(if ${CI},--out-format github-actions,)
+
+.PHONY: lint-yaml
+lint-yaml:
+ yamllint $(if ${CI},-f github,) --no-warnings .
+
+.PHONY: fmt
+fmt: ## Format code
+ golangci-lint run --fix
+
+deps: bin/golangci-lint bin/gotestsum yamllint
+deps: ## Install dependencies
+
+bin/gotestsum:
+ @mkdir -p bin
+ curl -L https://github.com/gotestyourself/gotestsum/releases/download/v${GOTESTSUM_VERSION}/gotestsum_${GOTESTSUM_VERSION}_${OS}_amd64.tar.gz | tar -zOxf - gotestsum > ./bin/gotestsum && chmod +x ./bin/gotestsum
+
+bin/golangci-lint:
+ @mkdir -p bin
+ curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | bash -s -- v${GOLANGCI_VERSION}
+
+.PHONY: yamllint
+yamllint:
+ pip3 install --user yamllint
# Add custom targets here
-include custom.mk
diff --git a/vendor/github.com/spf13/viper/README.md b/vendor/github.com/spf13/viper/README.md
index 4184d2a11..b96180b3b 100644
--- a/vendor/github.com/spf13/viper/README.md
+++ b/vendor/github.com/spf13/viper/README.md
@@ -11,7 +11,7 @@
[![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/spf13/viper/ci.yaml?branch=master&style=flat-square)](https://github.com/spf13/viper/actions?query=workflow%3ACI)
[![Join the chat at https://gitter.im/spf13/viper](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/spf13/viper?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
[![Go Report Card](https://goreportcard.com/badge/github.com/spf13/viper?style=flat-square)](https://goreportcard.com/report/github.com/spf13/viper)
-![Go Version](https://img.shields.io/badge/go%20version-%3E=1.16-61CFDD.svg?style=flat-square)
+![Go Version](https://img.shields.io/badge/go%20version-%3E=1.19-61CFDD.svg?style=flat-square)
[![PkgGoDev](https://pkg.go.dev/badge/mod/github.com/spf13/viper)](https://pkg.go.dev/mod/github.com/spf13/viper)
**Go configuration with fangs!**
@@ -30,6 +30,7 @@ Many Go projects are built using Viper including:
* [Meshery](https://github.com/meshery/meshery)
* [Bearer](https://github.com/bearer/bearer)
* [Coder](https://github.com/coder/coder)
+* [Vitess](https://vitess.io/)
## Install
@@ -140,7 +141,7 @@ if err := viper.ReadInConfig(); err != nil {
// Config file found and successfully parsed
```
-*NOTE [since 1.6]:* You can also have a file without an extension and specify the format programmaticaly. For those configuration files that lie in the home of the user without any extension like `.bashrc`
+*NOTE [since 1.6]:* You can also have a file without an extension and specify the format programmatically. For those configuration files that lie in the home of the user without any extension like `.bashrc`
### Writing Config Files
@@ -221,6 +222,7 @@ These could be from a command line flag, or from your own application logic.
```go
viper.Set("Verbose", true)
viper.Set("LogFile", LogFile)
+viper.Set("host.port", 5899) // set subset
```
### Registering and Using Aliases
@@ -416,6 +418,8 @@ in a Key/Value store such as etcd or Consul. These values take precedence over
default values, but are overridden by configuration values retrieved from disk,
flags, or environment variables.
+Viper supports multiple hosts. To use, pass a list of endpoints separated by `;`. For example `http://127.0.0.1:4001;http://127.0.0.1:4002`.
+
Viper uses [crypt](https://github.com/bketelsen/crypt) to retrieve
configuration from the K/V store, which means that you can store your
configuration values encrypted and have them automatically decrypted if you have
@@ -487,6 +491,15 @@ err := viper.ReadRemoteConfig()
Of course, you're allowed to use `SecureRemoteProvider` also
+
+#### NATS
+
+```go
+viper.AddRemoteProvider("nats", "nats://127.0.0.1:4222", "myapp.config")
+viper.SetConfigType("json")
+err := viper.ReadRemoteConfig()
+```
+
### Remote Key/Value Store Example - Encrypted
```go
@@ -534,24 +547,27 @@ go func(){
In Viper, there are a few ways to get a value depending on the value’s type.
The following functions and methods exist:
- * `Get(key string) : interface{}`
+ * `Get(key string) : any`
* `GetBool(key string) : bool`
* `GetFloat64(key string) : float64`
* `GetInt(key string) : int`
* `GetIntSlice(key string) : []int`
* `GetString(key string) : string`
- * `GetStringMap(key string) : map[string]interface{}`
+ * `GetStringMap(key string) : map[string]any`
* `GetStringMapString(key string) : map[string]string`
* `GetStringSlice(key string) : []string`
* `GetTime(key string) : time.Time`
* `GetDuration(key string) : time.Duration`
* `IsSet(key string) : bool`
- * `AllSettings() : map[string]interface{}`
+ * `AllSettings() : map[string]any`
One important thing to recognize is that each Get function will return a zero
value if it’s not found. To check if a given key exists, the `IsSet()` method
has been provided.
+The zero value will also be returned if the value is set, but fails to parse
+as the requested type.
+
Example:
```go
viper.GetString("logfile") // case-insensitive Setting & Getting
@@ -709,8 +725,8 @@ etc.
There are two methods to do this:
- * `Unmarshal(rawVal interface{}) : error`
- * `UnmarshalKey(key string, rawVal interface{}) : error`
+ * `Unmarshal(rawVal any) : error`
+ * `UnmarshalKey(key string, rawVal any) : error`
Example:
@@ -735,9 +751,9 @@ you have to change the delimiter:
```go
v := viper.NewWithOptions(viper.KeyDelimiter("::"))
-v.SetDefault("chart::values", map[string]interface{}{
- "ingress": map[string]interface{}{
- "annotations": map[string]interface{}{
+v.SetDefault("chart::values", map[string]any{
+ "ingress": map[string]any{
+ "annotations": map[string]any{
"traefik.frontend.rule.type": "PathPrefix",
"traefik.ingress.kubernetes.io/ssl-redirect": "true",
},
@@ -746,7 +762,7 @@ v.SetDefault("chart::values", map[string]interface{}{
type config struct {
Chart struct{
- Values map[string]interface{}
+ Values map[string]any
}
}
@@ -882,3 +898,31 @@ No, you will need to synchronize access to the viper yourself (for example by us
## Troubleshooting
See [TROUBLESHOOTING.md](TROUBLESHOOTING.md).
+
+## Development
+
+**For an optimal developer experience, it is recommended to install [Nix](https://nixos.org/download.html) and [direnv](https://direnv.net/docs/installation.html).**
+
+_Alternatively, install [Go](https://go.dev/dl/) on your computer then run `make deps` to install the rest of the dependencies._
+
+Run the test suite:
+
+```shell
+make test
+```
+
+Run linters:
+
+```shell
+make lint # pass -j option to run them in parallel
+```
+
+Some linter violations can automatically be fixed:
+
+```shell
+make fmt
+```
+
+## License
+
+The project is licensed under the [MIT License](LICENSE).
diff --git a/vendor/github.com/spf13/viper/experimental_logger.go b/vendor/github.com/spf13/viper/experimental_logger.go
deleted file mode 100644
index 206dad6a0..000000000
--- a/vendor/github.com/spf13/viper/experimental_logger.go
+++ /dev/null
@@ -1,11 +0,0 @@
-//go:build viper_logger
-// +build viper_logger
-
-package viper
-
-// WithLogger sets a custom logger.
-func WithLogger(l Logger) Option {
- return optionFunc(func(v *Viper) {
- v.logger = l
- })
-}
diff --git a/vendor/github.com/spf13/viper/viper_go1_15.go b/vendor/github.com/spf13/viper/file.go
similarity index 94%
rename from vendor/github.com/spf13/viper/viper_go1_15.go
rename to vendor/github.com/spf13/viper/file.go
index 19a771cbd..a54fe5a7a 100644
--- a/vendor/github.com/spf13/viper/viper_go1_15.go
+++ b/vendor/github.com/spf13/viper/file.go
@@ -1,5 +1,4 @@
-//go:build !go1.16 || !finder
-// +build !go1.16 !finder
+//go:build !finder
package viper
@@ -44,7 +43,7 @@ func (v *Viper) searchInPath(in string) (filename string) {
return ""
}
-// Check if file Exists
+// exists checks if file exists.
func exists(fs afero.Fs, path string) (bool, error) {
stat, err := fs.Stat(path)
if err == nil {
diff --git a/vendor/github.com/spf13/viper/file_finder.go b/vendor/github.com/spf13/viper/file_finder.go
new file mode 100644
index 000000000..d96a1bd22
--- /dev/null
+++ b/vendor/github.com/spf13/viper/file_finder.go
@@ -0,0 +1,38 @@
+//go:build finder
+
+package viper
+
+import (
+ "fmt"
+
+ "github.com/sagikazarmark/locafero"
+)
+
+// Search all configPaths for any config file.
+// Returns the first path that exists (and is a config file).
+func (v *Viper) findConfigFile() (string, error) {
+ var names []string
+
+ if v.configType != "" {
+ names = locafero.NameWithOptionalExtensions(v.configName, SupportedExts...)
+ } else {
+ names = locafero.NameWithExtensions(v.configName, SupportedExts...)
+ }
+
+ finder := locafero.Finder{
+ Paths: v.configPaths,
+ Names: names,
+ Type: locafero.FileTypeFile,
+ }
+
+ results, err := finder.Find(v.fs)
+ if err != nil {
+ return "", err
+ }
+
+ if len(results) == 0 {
+ return "", ConfigFileNotFoundError{v.configName, fmt.Sprintf("%s", v.configPaths)}
+ }
+
+ return results[0], nil
+}
diff --git a/vendor/github.com/spf13/viper/flags.go b/vendor/github.com/spf13/viper/flags.go
index b5ddbf5d4..de033ed58 100644
--- a/vendor/github.com/spf13/viper/flags.go
+++ b/vendor/github.com/spf13/viper/flags.go
@@ -30,8 +30,8 @@ func (p pflagValueSet) VisitAll(fn func(flag FlagValue)) {
})
}
-// pflagValue is a wrapper aroung *pflag.flag
-// that implements FlagValue
+// pflagValue is a wrapper around *pflag.flag
+// that implements FlagValue.
type pflagValue struct {
flag *pflag.Flag
}
diff --git a/vendor/github.com/spf13/viper/flake.lock b/vendor/github.com/spf13/viper/flake.lock
new file mode 100644
index 000000000..78da51090
--- /dev/null
+++ b/vendor/github.com/spf13/viper/flake.lock
@@ -0,0 +1,255 @@
+{
+ "nodes": {
+ "devenv": {
+ "inputs": {
+ "flake-compat": "flake-compat",
+ "nix": "nix",
+ "nixpkgs": "nixpkgs",
+ "pre-commit-hooks": "pre-commit-hooks"
+ },
+ "locked": {
+ "lastModified": 1687972261,
+ "narHash": "sha256-+mxvZfwMVoaZYETmuQWqTi/7T9UKoAE+WpdSQkOVJ2g=",
+ "owner": "cachix",
+ "repo": "devenv",
+ "rev": "e85df562088573305e55906eaa964341f8cb0d9f",
+ "type": "github"
+ },
+ "original": {
+ "owner": "cachix",
+ "repo": "devenv",
+ "type": "github"
+ }
+ },
+ "flake-compat": {
+ "flake": false,
+ "locked": {
+ "lastModified": 1673956053,
+ "narHash": "sha256-4gtG9iQuiKITOjNQQeQIpoIB6b16fm+504Ch3sNKLd8=",
+ "owner": "edolstra",
+ "repo": "flake-compat",
+ "rev": "35bb57c0c8d8b62bbfd284272c928ceb64ddbde9",
+ "type": "github"
+ },
+ "original": {
+ "owner": "edolstra",
+ "repo": "flake-compat",
+ "type": "github"
+ }
+ },
+ "flake-parts": {
+ "inputs": {
+ "nixpkgs-lib": "nixpkgs-lib"
+ },
+ "locked": {
+ "lastModified": 1687762428,
+ "narHash": "sha256-DIf7mi45PKo+s8dOYF+UlXHzE0Wl/+k3tXUyAoAnoGE=",
+ "owner": "hercules-ci",
+ "repo": "flake-parts",
+ "rev": "37dd7bb15791c86d55c5121740a1887ab55ee836",
+ "type": "github"
+ },
+ "original": {
+ "owner": "hercules-ci",
+ "repo": "flake-parts",
+ "type": "github"
+ }
+ },
+ "flake-utils": {
+ "locked": {
+ "lastModified": 1667395993,
+ "narHash": "sha256-nuEHfE/LcWyuSWnS8t12N1wc105Qtau+/OdUAjtQ0rA=",
+ "owner": "numtide",
+ "repo": "flake-utils",
+ "rev": "5aed5285a952e0b949eb3ba02c12fa4fcfef535f",
+ "type": "github"
+ },
+ "original": {
+ "owner": "numtide",
+ "repo": "flake-utils",
+ "type": "github"
+ }
+ },
+ "gitignore": {
+ "inputs": {
+ "nixpkgs": [
+ "devenv",
+ "pre-commit-hooks",
+ "nixpkgs"
+ ]
+ },
+ "locked": {
+ "lastModified": 1660459072,
+ "narHash": "sha256-8DFJjXG8zqoONA1vXtgeKXy68KdJL5UaXR8NtVMUbx8=",
+ "owner": "hercules-ci",
+ "repo": "gitignore.nix",
+ "rev": "a20de23b925fd8264fd7fad6454652e142fd7f73",
+ "type": "github"
+ },
+ "original": {
+ "owner": "hercules-ci",
+ "repo": "gitignore.nix",
+ "type": "github"
+ }
+ },
+ "lowdown-src": {
+ "flake": false,
+ "locked": {
+ "lastModified": 1633514407,
+ "narHash": "sha256-Dw32tiMjdK9t3ETl5fzGrutQTzh2rufgZV4A/BbxuD4=",
+ "owner": "kristapsdz",
+ "repo": "lowdown",
+ "rev": "d2c2b44ff6c27b936ec27358a2653caaef8f73b8",
+ "type": "github"
+ },
+ "original": {
+ "owner": "kristapsdz",
+ "repo": "lowdown",
+ "type": "github"
+ }
+ },
+ "nix": {
+ "inputs": {
+ "lowdown-src": "lowdown-src",
+ "nixpkgs": [
+ "devenv",
+ "nixpkgs"
+ ],
+ "nixpkgs-regression": "nixpkgs-regression"
+ },
+ "locked": {
+ "lastModified": 1676545802,
+ "narHash": "sha256-EK4rZ+Hd5hsvXnzSzk2ikhStJnD63odF7SzsQ8CuSPU=",
+ "owner": "domenkozar",
+ "repo": "nix",
+ "rev": "7c91803598ffbcfe4a55c44ac6d49b2cf07a527f",
+ "type": "github"
+ },
+ "original": {
+ "owner": "domenkozar",
+ "ref": "relaxed-flakes",
+ "repo": "nix",
+ "type": "github"
+ }
+ },
+ "nixpkgs": {
+ "locked": {
+ "lastModified": 1678875422,
+ "narHash": "sha256-T3o6NcQPwXjxJMn2shz86Chch4ljXgZn746c2caGxd8=",
+ "owner": "NixOS",
+ "repo": "nixpkgs",
+ "rev": "126f49a01de5b7e35a43fd43f891ecf6d3a51459",
+ "type": "github"
+ },
+ "original": {
+ "owner": "NixOS",
+ "ref": "nixpkgs-unstable",
+ "repo": "nixpkgs",
+ "type": "github"
+ }
+ },
+ "nixpkgs-lib": {
+ "locked": {
+ "dir": "lib",
+ "lastModified": 1685564631,
+ "narHash": "sha256-8ywr3AkblY4++3lIVxmrWZFzac7+f32ZEhH/A8pNscI=",
+ "owner": "NixOS",
+ "repo": "nixpkgs",
+ "rev": "4f53efe34b3a8877ac923b9350c874e3dcd5dc0a",
+ "type": "github"
+ },
+ "original": {
+ "dir": "lib",
+ "owner": "NixOS",
+ "ref": "nixos-unstable",
+ "repo": "nixpkgs",
+ "type": "github"
+ }
+ },
+ "nixpkgs-regression": {
+ "locked": {
+ "lastModified": 1643052045,
+ "narHash": "sha256-uGJ0VXIhWKGXxkeNnq4TvV3CIOkUJ3PAoLZ3HMzNVMw=",
+ "owner": "NixOS",
+ "repo": "nixpkgs",
+ "rev": "215d4d0fd80ca5163643b03a33fde804a29cc1e2",
+ "type": "github"
+ },
+ "original": {
+ "owner": "NixOS",
+ "repo": "nixpkgs",
+ "rev": "215d4d0fd80ca5163643b03a33fde804a29cc1e2",
+ "type": "github"
+ }
+ },
+ "nixpkgs-stable": {
+ "locked": {
+ "lastModified": 1678872516,
+ "narHash": "sha256-/E1YwtMtFAu2KUQKV/1+KFuReYPANM2Rzehk84VxVoc=",
+ "owner": "NixOS",
+ "repo": "nixpkgs",
+ "rev": "9b8e5abb18324c7fe9f07cb100c3cd4a29cda8b8",
+ "type": "github"
+ },
+ "original": {
+ "owner": "NixOS",
+ "ref": "nixos-22.11",
+ "repo": "nixpkgs",
+ "type": "github"
+ }
+ },
+ "nixpkgs_2": {
+ "locked": {
+ "lastModified": 1687886075,
+ "narHash": "sha256-PeayJDDDy+uw1Ats4moZnRdL1OFuZm1Tj+KiHlD67+o=",
+ "owner": "NixOS",
+ "repo": "nixpkgs",
+ "rev": "a565059a348422af5af9026b5174dc5c0dcefdae",
+ "type": "github"
+ },
+ "original": {
+ "owner": "NixOS",
+ "ref": "nixpkgs-unstable",
+ "repo": "nixpkgs",
+ "type": "github"
+ }
+ },
+ "pre-commit-hooks": {
+ "inputs": {
+ "flake-compat": [
+ "devenv",
+ "flake-compat"
+ ],
+ "flake-utils": "flake-utils",
+ "gitignore": "gitignore",
+ "nixpkgs": [
+ "devenv",
+ "nixpkgs"
+ ],
+ "nixpkgs-stable": "nixpkgs-stable"
+ },
+ "locked": {
+ "lastModified": 1686050334,
+ "narHash": "sha256-R0mczWjDzBpIvM3XXhO908X5e2CQqjyh/gFbwZk/7/Q=",
+ "owner": "cachix",
+ "repo": "pre-commit-hooks.nix",
+ "rev": "6881eb2ae5d8a3516e34714e7a90d9d95914c4dc",
+ "type": "github"
+ },
+ "original": {
+ "owner": "cachix",
+ "repo": "pre-commit-hooks.nix",
+ "type": "github"
+ }
+ },
+ "root": {
+ "inputs": {
+ "devenv": "devenv",
+ "flake-parts": "flake-parts",
+ "nixpkgs": "nixpkgs_2"
+ }
+ }
+ },
+ "root": "root",
+ "version": 7
+}
diff --git a/vendor/github.com/spf13/viper/flake.nix b/vendor/github.com/spf13/viper/flake.nix
new file mode 100644
index 000000000..9b26c3fcf
--- /dev/null
+++ b/vendor/github.com/spf13/viper/flake.nix
@@ -0,0 +1,56 @@
+{
+ description = "Viper";
+
+ inputs = {
+ nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
+ flake-parts.url = "github:hercules-ci/flake-parts";
+ devenv.url = "github:cachix/devenv";
+ };
+
+ outputs = inputs@{ flake-parts, ... }:
+ flake-parts.lib.mkFlake { inherit inputs; } {
+ imports = [
+ inputs.devenv.flakeModule
+ ];
+
+ systems = [ "x86_64-linux" "x86_64-darwin" "aarch64-darwin" ];
+
+ perSystem = { config, self', inputs', pkgs, system, ... }: rec {
+ devenv.shells = {
+ default = {
+ languages = {
+ go.enable = true;
+ };
+
+ pre-commit.hooks = {
+ nixpkgs-fmt.enable = true;
+ yamllint.enable = true;
+ };
+
+ packages = with pkgs; [
+ gnumake
+
+ golangci-lint
+ yamllint
+ ];
+
+ scripts = {
+ versions.exec = ''
+ go version
+ golangci-lint version
+ '';
+ };
+
+ enterShell = ''
+ versions
+ '';
+
+ # https://github.com/cachix/devenv/issues/528#issuecomment-1556108767
+ containers = pkgs.lib.mkForce { };
+ };
+
+ ci = devenv.shells.default;
+ };
+ };
+ };
+}
diff --git a/vendor/github.com/spf13/viper/fs.go b/vendor/github.com/spf13/viper/fs.go
deleted file mode 100644
index ecb1769e5..000000000
--- a/vendor/github.com/spf13/viper/fs.go
+++ /dev/null
@@ -1,65 +0,0 @@
-//go:build go1.16 && finder
-// +build go1.16,finder
-
-package viper
-
-import (
- "errors"
- "io/fs"
- "path"
-)
-
-type finder struct {
- paths []string
- fileNames []string
- extensions []string
-
- withoutExtension bool
-}
-
-func (f finder) Find(fsys fs.FS) (string, error) {
- for _, searchPath := range f.paths {
- for _, fileName := range f.fileNames {
- for _, extension := range f.extensions {
- filePath := path.Join(searchPath, fileName+"."+extension)
-
- ok, err := fileExists(fsys, filePath)
- if err != nil {
- return "", err
- }
-
- if ok {
- return filePath, nil
- }
- }
-
- if f.withoutExtension {
- filePath := path.Join(searchPath, fileName)
-
- ok, err := fileExists(fsys, filePath)
- if err != nil {
- return "", err
- }
-
- if ok {
- return filePath, nil
- }
- }
- }
- }
-
- return "", nil
-}
-
-func fileExists(fsys fs.FS, filePath string) (bool, error) {
- fileInfo, err := fs.Stat(fsys, filePath)
- if err == nil {
- return !fileInfo.IsDir(), nil
- }
-
- if errors.Is(err, fs.ErrNotExist) {
- return false, nil
- }
-
- return false, err
-}
diff --git a/vendor/github.com/spf13/viper/internal/encoding/decoder.go b/vendor/github.com/spf13/viper/internal/encoding/decoder.go
index f472e9ff1..8a7b1dbc9 100644
--- a/vendor/github.com/spf13/viper/internal/encoding/decoder.go
+++ b/vendor/github.com/spf13/viper/internal/encoding/decoder.go
@@ -5,9 +5,9 @@ import (
)
// Decoder decodes the contents of b into v.
-// It's primarily used for decoding contents of a file into a map[string]interface{}.
+// It's primarily used for decoding contents of a file into a map[string]any.
type Decoder interface {
- Decode(b []byte, v map[string]interface{}) error
+ Decode(b []byte, v map[string]any) error
}
const (
@@ -48,7 +48,7 @@ func (e *DecoderRegistry) RegisterDecoder(format string, enc Decoder) error {
}
// Decode calls the underlying Decoder based on the format.
-func (e *DecoderRegistry) Decode(format string, b []byte, v map[string]interface{}) error {
+func (e *DecoderRegistry) Decode(format string, b []byte, v map[string]any) error {
e.mu.RLock()
decoder, ok := e.decoders[format]
e.mu.RUnlock()
diff --git a/vendor/github.com/spf13/viper/internal/encoding/dotenv/codec.go b/vendor/github.com/spf13/viper/internal/encoding/dotenv/codec.go
index 4485063b6..3ebc76f02 100644
--- a/vendor/github.com/spf13/viper/internal/encoding/dotenv/codec.go
+++ b/vendor/github.com/spf13/viper/internal/encoding/dotenv/codec.go
@@ -15,8 +15,8 @@ const keyDelimiter = "_"
// (commonly called as dotenv format).
type Codec struct{}
-func (Codec) Encode(v map[string]interface{}) ([]byte, error) {
- flattened := map[string]interface{}{}
+func (Codec) Encode(v map[string]any) ([]byte, error) {
+ flattened := map[string]any{}
flattened = flattenAndMergeMap(flattened, v, "", keyDelimiter)
@@ -40,7 +40,7 @@ func (Codec) Encode(v map[string]interface{}) ([]byte, error) {
return buf.Bytes(), nil
}
-func (Codec) Decode(b []byte, v map[string]interface{}) error {
+func (Codec) Decode(b []byte, v map[string]any) error {
var buf bytes.Buffer
_, err := buf.Write(b)
diff --git a/vendor/github.com/spf13/viper/internal/encoding/dotenv/map_utils.go b/vendor/github.com/spf13/viper/internal/encoding/dotenv/map_utils.go
index ce6e6efa3..8bfe0a9de 100644
--- a/vendor/github.com/spf13/viper/internal/encoding/dotenv/map_utils.go
+++ b/vendor/github.com/spf13/viper/internal/encoding/dotenv/map_utils.go
@@ -7,27 +7,27 @@ import (
)
// flattenAndMergeMap recursively flattens the given map into a new map
-// Code is based on the function with the same name in tha main package.
-// TODO: move it to a common place
-func flattenAndMergeMap(shadow map[string]interface{}, m map[string]interface{}, prefix string, delimiter string) map[string]interface{} {
+// Code is based on the function with the same name in the main package.
+// TODO: move it to a common place.
+func flattenAndMergeMap(shadow, m map[string]any, prefix, delimiter string) map[string]any {
if shadow != nil && prefix != "" && shadow[prefix] != nil {
// prefix is shadowed => nothing more to flatten
return shadow
}
if shadow == nil {
- shadow = make(map[string]interface{})
+ shadow = make(map[string]any)
}
- var m2 map[string]interface{}
+ var m2 map[string]any
if prefix != "" {
prefix += delimiter
}
for k, val := range m {
fullKey := prefix + k
- switch val.(type) {
- case map[string]interface{}:
- m2 = val.(map[string]interface{})
- case map[interface{}]interface{}:
+ switch val := val.(type) {
+ case map[string]any:
+ m2 = val
+ case map[any]any:
m2 = cast.ToStringMap(val)
default:
// immediate value
diff --git a/vendor/github.com/spf13/viper/internal/encoding/encoder.go b/vendor/github.com/spf13/viper/internal/encoding/encoder.go
index 2341bf235..659585962 100644
--- a/vendor/github.com/spf13/viper/internal/encoding/encoder.go
+++ b/vendor/github.com/spf13/viper/internal/encoding/encoder.go
@@ -5,9 +5,9 @@ import (
)
// Encoder encodes the contents of v into a byte representation.
-// It's primarily used for encoding a map[string]interface{} into a file format.
+// It's primarily used for encoding a map[string]any into a file format.
type Encoder interface {
- Encode(v map[string]interface{}) ([]byte, error)
+ Encode(v map[string]any) ([]byte, error)
}
const (
@@ -47,7 +47,7 @@ func (e *EncoderRegistry) RegisterEncoder(format string, enc Encoder) error {
return nil
}
-func (e *EncoderRegistry) Encode(format string, v map[string]interface{}) ([]byte, error) {
+func (e *EncoderRegistry) Encode(format string, v map[string]any) ([]byte, error) {
e.mu.RLock()
encoder, ok := e.encoders[format]
e.mu.RUnlock()
diff --git a/vendor/github.com/spf13/viper/internal/encoding/hcl/codec.go b/vendor/github.com/spf13/viper/internal/encoding/hcl/codec.go
index 7fde8e4bc..d7fa8a1b7 100644
--- a/vendor/github.com/spf13/viper/internal/encoding/hcl/codec.go
+++ b/vendor/github.com/spf13/viper/internal/encoding/hcl/codec.go
@@ -12,7 +12,7 @@ import (
// TODO: add printer config to the codec?
type Codec struct{}
-func (Codec) Encode(v map[string]interface{}) ([]byte, error) {
+func (Codec) Encode(v map[string]any) ([]byte, error) {
b, err := json.Marshal(v)
if err != nil {
return nil, err
@@ -35,6 +35,6 @@ func (Codec) Encode(v map[string]interface{}) ([]byte, error) {
return buf.Bytes(), nil
}
-func (Codec) Decode(b []byte, v map[string]interface{}) error {
+func (Codec) Decode(b []byte, v map[string]any) error {
return hcl.Unmarshal(b, &v)
}
diff --git a/vendor/github.com/spf13/viper/internal/encoding/ini/codec.go b/vendor/github.com/spf13/viper/internal/encoding/ini/codec.go
index 9acd87fc3..d91cf59d2 100644
--- a/vendor/github.com/spf13/viper/internal/encoding/ini/codec.go
+++ b/vendor/github.com/spf13/viper/internal/encoding/ini/codec.go
@@ -19,11 +19,11 @@ type Codec struct {
LoadOptions LoadOptions
}
-func (c Codec) Encode(v map[string]interface{}) ([]byte, error) {
+func (c Codec) Encode(v map[string]any) ([]byte, error) {
cfg := ini.Empty()
ini.PrettyFormat = false
- flattened := map[string]interface{}{}
+ flattened := map[string]any{}
flattened = flattenAndMergeMap(flattened, v, "", c.keyDelimiter())
@@ -62,7 +62,7 @@ func (c Codec) Encode(v map[string]interface{}) ([]byte, error) {
return buf.Bytes(), nil
}
-func (c Codec) Decode(b []byte, v map[string]interface{}) error {
+func (c Codec) Decode(b []byte, v map[string]any) error {
cfg := ini.Empty(c.LoadOptions)
err := cfg.Append(b)
diff --git a/vendor/github.com/spf13/viper/internal/encoding/ini/map_utils.go b/vendor/github.com/spf13/viper/internal/encoding/ini/map_utils.go
index 8329856b5..490ab594e 100644
--- a/vendor/github.com/spf13/viper/internal/encoding/ini/map_utils.go
+++ b/vendor/github.com/spf13/viper/internal/encoding/ini/map_utils.go
@@ -15,22 +15,22 @@ import (
// In case intermediate keys do not exist, or map to a non-map value,
// a new map is created and inserted, and the search continues from there:
// the initial map "m" may be modified!
-func deepSearch(m map[string]interface{}, path []string) map[string]interface{} {
+func deepSearch(m map[string]any, path []string) map[string]any {
for _, k := range path {
m2, ok := m[k]
if !ok {
// intermediate key does not exist
// => create it and continue from there
- m3 := make(map[string]interface{})
+ m3 := make(map[string]any)
m[k] = m3
m = m3
continue
}
- m3, ok := m2.(map[string]interface{})
+ m3, ok := m2.(map[string]any)
if !ok {
// intermediate key is a value
// => replace with a new map
- m3 = make(map[string]interface{})
+ m3 = make(map[string]any)
m[k] = m3
}
// continue search from here
@@ -40,27 +40,27 @@ func deepSearch(m map[string]interface{}, path []string) map[string]interface{}
}
// flattenAndMergeMap recursively flattens the given map into a new map
-// Code is based on the function with the same name in tha main package.
-// TODO: move it to a common place
-func flattenAndMergeMap(shadow map[string]interface{}, m map[string]interface{}, prefix string, delimiter string) map[string]interface{} {
+// Code is based on the function with the same name in the main package.
+// TODO: move it to a common place.
+func flattenAndMergeMap(shadow, m map[string]any, prefix, delimiter string) map[string]any {
if shadow != nil && prefix != "" && shadow[prefix] != nil {
// prefix is shadowed => nothing more to flatten
return shadow
}
if shadow == nil {
- shadow = make(map[string]interface{})
+ shadow = make(map[string]any)
}
- var m2 map[string]interface{}
+ var m2 map[string]any
if prefix != "" {
prefix += delimiter
}
for k, val := range m {
fullKey := prefix + k
- switch val.(type) {
- case map[string]interface{}:
- m2 = val.(map[string]interface{})
- case map[interface{}]interface{}:
+ switch val := val.(type) {
+ case map[string]any:
+ m2 = val
+ case map[any]any:
m2 = cast.ToStringMap(val)
default:
// immediate value
diff --git a/vendor/github.com/spf13/viper/internal/encoding/javaproperties/codec.go b/vendor/github.com/spf13/viper/internal/encoding/javaproperties/codec.go
index b8a2251c1..e92e5172c 100644
--- a/vendor/github.com/spf13/viper/internal/encoding/javaproperties/codec.go
+++ b/vendor/github.com/spf13/viper/internal/encoding/javaproperties/codec.go
@@ -20,12 +20,12 @@ type Codec struct {
Properties *properties.Properties
}
-func (c *Codec) Encode(v map[string]interface{}) ([]byte, error) {
+func (c *Codec) Encode(v map[string]any) ([]byte, error) {
if c.Properties == nil {
c.Properties = properties.NewProperties()
}
- flattened := map[string]interface{}{}
+ flattened := map[string]any{}
flattened = flattenAndMergeMap(flattened, v, "", c.keyDelimiter())
@@ -54,7 +54,7 @@ func (c *Codec) Encode(v map[string]interface{}) ([]byte, error) {
return buf.Bytes(), nil
}
-func (c *Codec) Decode(b []byte, v map[string]interface{}) error {
+func (c *Codec) Decode(b []byte, v map[string]any) error {
var err error
c.Properties, err = properties.Load(b, properties.UTF8)
if err != nil {
diff --git a/vendor/github.com/spf13/viper/internal/encoding/javaproperties/map_utils.go b/vendor/github.com/spf13/viper/internal/encoding/javaproperties/map_utils.go
index 93755cac1..6e1aff223 100644
--- a/vendor/github.com/spf13/viper/internal/encoding/javaproperties/map_utils.go
+++ b/vendor/github.com/spf13/viper/internal/encoding/javaproperties/map_utils.go
@@ -15,22 +15,22 @@ import (
// In case intermediate keys do not exist, or map to a non-map value,
// a new map is created and inserted, and the search continues from there:
// the initial map "m" may be modified!
-func deepSearch(m map[string]interface{}, path []string) map[string]interface{} {
+func deepSearch(m map[string]any, path []string) map[string]any {
for _, k := range path {
m2, ok := m[k]
if !ok {
// intermediate key does not exist
// => create it and continue from there
- m3 := make(map[string]interface{})
+ m3 := make(map[string]any)
m[k] = m3
m = m3
continue
}
- m3, ok := m2.(map[string]interface{})
+ m3, ok := m2.(map[string]any)
if !ok {
// intermediate key is a value
// => replace with a new map
- m3 = make(map[string]interface{})
+ m3 = make(map[string]any)
m[k] = m3
}
// continue search from here
@@ -40,27 +40,27 @@ func deepSearch(m map[string]interface{}, path []string) map[string]interface{}
}
// flattenAndMergeMap recursively flattens the given map into a new map
-// Code is based on the function with the same name in tha main package.
-// TODO: move it to a common place
-func flattenAndMergeMap(shadow map[string]interface{}, m map[string]interface{}, prefix string, delimiter string) map[string]interface{} {
+// Code is based on the function with the same name in the main package.
+// TODO: move it to a common place.
+func flattenAndMergeMap(shadow, m map[string]any, prefix, delimiter string) map[string]any {
if shadow != nil && prefix != "" && shadow[prefix] != nil {
// prefix is shadowed => nothing more to flatten
return shadow
}
if shadow == nil {
- shadow = make(map[string]interface{})
+ shadow = make(map[string]any)
}
- var m2 map[string]interface{}
+ var m2 map[string]any
if prefix != "" {
prefix += delimiter
}
for k, val := range m {
fullKey := prefix + k
- switch val.(type) {
- case map[string]interface{}:
- m2 = val.(map[string]interface{})
- case map[interface{}]interface{}:
+ switch val := val.(type) {
+ case map[string]any:
+ m2 = val
+ case map[any]any:
m2 = cast.ToStringMap(val)
default:
// immediate value
diff --git a/vendor/github.com/spf13/viper/internal/encoding/json/codec.go b/vendor/github.com/spf13/viper/internal/encoding/json/codec.go
index 1b7caaceb..da7546b5a 100644
--- a/vendor/github.com/spf13/viper/internal/encoding/json/codec.go
+++ b/vendor/github.com/spf13/viper/internal/encoding/json/codec.go
@@ -7,11 +7,11 @@ import (
// Codec implements the encoding.Encoder and encoding.Decoder interfaces for JSON encoding.
type Codec struct{}
-func (Codec) Encode(v map[string]interface{}) ([]byte, error) {
+func (Codec) Encode(v map[string]any) ([]byte, error) {
// TODO: expose prefix and indent in the Codec as setting?
return json.MarshalIndent(v, "", " ")
}
-func (Codec) Decode(b []byte, v map[string]interface{}) error {
+func (Codec) Decode(b []byte, v map[string]any) error {
return json.Unmarshal(b, &v)
}
diff --git a/vendor/github.com/spf13/viper/internal/encoding/toml/codec.go b/vendor/github.com/spf13/viper/internal/encoding/toml/codec.go
index a993c5994..c70aa8d28 100644
--- a/vendor/github.com/spf13/viper/internal/encoding/toml/codec.go
+++ b/vendor/github.com/spf13/viper/internal/encoding/toml/codec.go
@@ -7,10 +7,10 @@ import (
// Codec implements the encoding.Encoder and encoding.Decoder interfaces for TOML encoding.
type Codec struct{}
-func (Codec) Encode(v map[string]interface{}) ([]byte, error) {
+func (Codec) Encode(v map[string]any) ([]byte, error) {
return toml.Marshal(v)
}
-func (Codec) Decode(b []byte, v map[string]interface{}) error {
+func (Codec) Decode(b []byte, v map[string]any) error {
return toml.Unmarshal(b, &v)
}
diff --git a/vendor/github.com/spf13/viper/internal/encoding/yaml/codec.go b/vendor/github.com/spf13/viper/internal/encoding/yaml/codec.go
index 82dc136a3..036879249 100644
--- a/vendor/github.com/spf13/viper/internal/encoding/yaml/codec.go
+++ b/vendor/github.com/spf13/viper/internal/encoding/yaml/codec.go
@@ -5,10 +5,10 @@ import "gopkg.in/yaml.v3"
// Codec implements the encoding.Encoder and encoding.Decoder interfaces for YAML encoding.
type Codec struct{}
-func (Codec) Encode(v map[string]interface{}) ([]byte, error) {
+func (Codec) Encode(v map[string]any) ([]byte, error) {
return yaml.Marshal(v)
}
-func (Codec) Decode(b []byte, v map[string]interface{}) error {
+func (Codec) Decode(b []byte, v map[string]any) error {
return yaml.Unmarshal(b, &v)
}
diff --git a/vendor/github.com/spf13/viper/internal/features/bind_struct.go b/vendor/github.com/spf13/viper/internal/features/bind_struct.go
new file mode 100644
index 000000000..89302c216
--- /dev/null
+++ b/vendor/github.com/spf13/viper/internal/features/bind_struct.go
@@ -0,0 +1,5 @@
+//go:build viper_bind_struct
+
+package features
+
+const BindStruct = true
diff --git a/vendor/github.com/spf13/viper/internal/features/bind_struct_default.go b/vendor/github.com/spf13/viper/internal/features/bind_struct_default.go
new file mode 100644
index 000000000..edfaf73b6
--- /dev/null
+++ b/vendor/github.com/spf13/viper/internal/features/bind_struct_default.go
@@ -0,0 +1,5 @@
+//go:build !viper_bind_struct
+
+package features
+
+const BindStruct = false
diff --git a/vendor/github.com/spf13/viper/logger.go b/vendor/github.com/spf13/viper/logger.go
index a64e1446c..8938053b3 100644
--- a/vendor/github.com/spf13/viper/logger.go
+++ b/vendor/github.com/spf13/viper/logger.go
@@ -1,77 +1,68 @@
package viper
import (
- "fmt"
+ "context"
- jww "github.com/spf13/jwalterweatherman"
+ slog "github.com/sagikazarmark/slog-shim"
)
// Logger is a unified interface for various logging use cases and practices, including:
// - leveled logging
// - structured logging
+//
+// Deprecated: use `log/slog` instead.
type Logger interface {
// Trace logs a Trace event.
//
// Even more fine-grained information than Debug events.
// Loggers not supporting this level should fall back to Debug.
- Trace(msg string, keyvals ...interface{})
+ Trace(msg string, keyvals ...any)
// Debug logs a Debug event.
//
// A verbose series of information events.
// They are useful when debugging the system.
- Debug(msg string, keyvals ...interface{})
+ Debug(msg string, keyvals ...any)
// Info logs an Info event.
//
// General information about what's happening inside the system.
- Info(msg string, keyvals ...interface{})
+ Info(msg string, keyvals ...any)
// Warn logs a Warn(ing) event.
//
// Non-critical events that should be looked at.
- Warn(msg string, keyvals ...interface{})
+ Warn(msg string, keyvals ...any)
// Error logs an Error event.
//
// Critical events that require immediate attention.
// Loggers commonly provide Fatal and Panic levels above Error level,
- // but exiting and panicing is out of scope for a logging library.
- Error(msg string, keyvals ...interface{})
+ // but exiting and panicking is out of scope for a logging library.
+ Error(msg string, keyvals ...any)
}
-type jwwLogger struct{}
-
-func (jwwLogger) Trace(msg string, keyvals ...interface{}) {
- jww.TRACE.Printf(jwwLogMessage(msg, keyvals...))
+// WithLogger sets a custom logger.
+func WithLogger(l *slog.Logger) Option {
+ return optionFunc(func(v *Viper) {
+ v.logger = l
+ })
}
-func (jwwLogger) Debug(msg string, keyvals ...interface{}) {
- jww.DEBUG.Printf(jwwLogMessage(msg, keyvals...))
+type discardHandler struct{}
+
+func (n *discardHandler) Enabled(_ context.Context, _ slog.Level) bool {
+ return false
}
-func (jwwLogger) Info(msg string, keyvals ...interface{}) {
- jww.INFO.Printf(jwwLogMessage(msg, keyvals...))
+func (n *discardHandler) Handle(_ context.Context, _ slog.Record) error {
+ return nil
}
-func (jwwLogger) Warn(msg string, keyvals ...interface{}) {
- jww.WARN.Printf(jwwLogMessage(msg, keyvals...))
+func (n *discardHandler) WithAttrs(_ []slog.Attr) slog.Handler {
+ return n
}
-func (jwwLogger) Error(msg string, keyvals ...interface{}) {
- jww.ERROR.Printf(jwwLogMessage(msg, keyvals...))
-}
-
-func jwwLogMessage(msg string, keyvals ...interface{}) string {
- out := msg
-
- if len(keyvals) > 0 && len(keyvals)%2 == 1 {
- keyvals = append(keyvals, nil)
- }
-
- for i := 0; i <= len(keyvals)-2; i += 2 {
- out = fmt.Sprintf("%s %v=%v", out, keyvals[i], keyvals[i+1])
- }
-
- return out
+func (n *discardHandler) WithGroup(_ string) slog.Handler {
+ return n
}
diff --git a/vendor/github.com/spf13/viper/util.go b/vendor/github.com/spf13/viper/util.go
index 95009a147..117c6ac31 100644
--- a/vendor/github.com/spf13/viper/util.go
+++ b/vendor/github.com/spf13/viper/util.go
@@ -18,6 +18,7 @@ import (
"strings"
"unicode"
+ slog "github.com/sagikazarmark/slog-shim"
"github.com/spf13/cast"
)
@@ -38,11 +39,11 @@ func (pe ConfigParseError) Unwrap() error {
// toCaseInsensitiveValue checks if the value is a map;
// if so, create a copy and lower-case the keys recursively.
-func toCaseInsensitiveValue(value interface{}) interface{} {
+func toCaseInsensitiveValue(value any) any {
switch v := value.(type) {
- case map[interface{}]interface{}:
+ case map[any]any:
value = copyAndInsensitiviseMap(cast.ToStringMap(v))
- case map[string]interface{}:
+ case map[string]any:
value = copyAndInsensitiviseMap(v)
}
@@ -51,15 +52,15 @@ func toCaseInsensitiveValue(value interface{}) interface{} {
// copyAndInsensitiviseMap behaves like insensitiviseMap, but creates a copy of
// any map it makes case insensitive.
-func copyAndInsensitiviseMap(m map[string]interface{}) map[string]interface{} {
- nm := make(map[string]interface{})
+func copyAndInsensitiviseMap(m map[string]any) map[string]any {
+ nm := make(map[string]any)
for key, val := range m {
lkey := strings.ToLower(key)
switch v := val.(type) {
- case map[interface{}]interface{}:
+ case map[any]any:
nm[lkey] = copyAndInsensitiviseMap(cast.ToStringMap(v))
- case map[string]interface{}:
+ case map[string]any:
nm[lkey] = copyAndInsensitiviseMap(v)
default:
nm[lkey] = v
@@ -69,23 +70,23 @@ func copyAndInsensitiviseMap(m map[string]interface{}) map[string]interface{} {
return nm
}
-func insensitiviseVal(val interface{}) interface{} {
- switch val.(type) {
- case map[interface{}]interface{}:
+func insensitiviseVal(val any) any {
+ switch v := val.(type) {
+ case map[any]any:
// nested map: cast and recursively insensitivise
val = cast.ToStringMap(val)
- insensitiviseMap(val.(map[string]interface{}))
- case map[string]interface{}:
+ insensitiviseMap(val.(map[string]any))
+ case map[string]any:
// nested map: recursively insensitivise
- insensitiviseMap(val.(map[string]interface{}))
- case []interface{}:
+ insensitiviseMap(v)
+ case []any:
// nested array: recursively insensitivise
- insensitiveArray(val.([]interface{}))
+ insensitiveArray(v)
}
return val
}
-func insensitiviseMap(m map[string]interface{}) {
+func insensitiviseMap(m map[string]any) {
for key, val := range m {
val = insensitiviseVal(val)
lower := strings.ToLower(key)
@@ -98,13 +99,13 @@ func insensitiviseMap(m map[string]interface{}) {
}
}
-func insensitiveArray(a []interface{}) {
+func insensitiveArray(a []any) {
for i, val := range a {
a[i] = insensitiviseVal(val)
}
}
-func absPathify(logger Logger, inPath string) string {
+func absPathify(logger *slog.Logger, inPath string) string {
logger.Info("trying to resolve absolute path", "path", inPath)
if inPath == "$HOME" || strings.HasPrefix(inPath, "$HOME"+string(os.PathSeparator)) {
@@ -155,7 +156,7 @@ func safeMul(a, b uint) uint {
return c
}
-// parseSizeInBytes converts strings like 1GB or 12 mb into an unsigned integer number of bytes
+// parseSizeInBytes converts strings like 1GB or 12 mb into an unsigned integer number of bytes.
func parseSizeInBytes(sizeStr string) uint {
sizeStr = strings.TrimSpace(sizeStr)
lastChar := len(sizeStr) - 1
@@ -197,22 +198,22 @@ func parseSizeInBytes(sizeStr string) uint {
// In case intermediate keys do not exist, or map to a non-map value,
// a new map is created and inserted, and the search continues from there:
// the initial map "m" may be modified!
-func deepSearch(m map[string]interface{}, path []string) map[string]interface{} {
+func deepSearch(m map[string]any, path []string) map[string]any {
for _, k := range path {
m2, ok := m[k]
if !ok {
// intermediate key does not exist
// => create it and continue from there
- m3 := make(map[string]interface{})
+ m3 := make(map[string]any)
m[k] = m3
m = m3
continue
}
- m3, ok := m2.(map[string]interface{})
+ m3, ok := m2.(map[string]any)
if !ok {
// intermediate key is a value
// => replace with a new map
- m3 = make(map[string]interface{})
+ m3 = make(map[string]any)
m[k] = m3
}
// continue search from here
diff --git a/vendor/github.com/spf13/viper/viper.go b/vendor/github.com/spf13/viper/viper.go
index 7fb1e1913..20eb4da17 100644
--- a/vendor/github.com/spf13/viper/viper.go
+++ b/vendor/github.com/spf13/viper/viper.go
@@ -35,6 +35,7 @@ import (
"github.com/fsnotify/fsnotify"
"github.com/mitchellh/mapstructure"
+ slog "github.com/sagikazarmark/slog-shim"
"github.com/spf13/afero"
"github.com/spf13/cast"
"github.com/spf13/pflag"
@@ -47,6 +48,7 @@ import (
"github.com/spf13/viper/internal/encoding/json"
"github.com/spf13/viper/internal/encoding/toml"
"github.com/spf13/viper/internal/encoding/yaml"
+ "github.com/spf13/viper/internal/features"
)
// ConfigMarshalError happens when failing to marshal the configuration.
@@ -76,7 +78,7 @@ type remoteConfigFactory interface {
WatchChannel(rp RemoteProvider) (<-chan *RemoteResponse, chan bool)
}
-// RemoteConfig is optional, see the remote package
+// RemoteConfig is optional, see the remote package.
var RemoteConfig remoteConfigFactory
// UnsupportedConfigError denotes encountering an unsupported
@@ -101,7 +103,7 @@ func (str UnsupportedRemoteProviderError) Error() string {
// pull the configuration from the remote provider.
type RemoteConfigError string
-// Error returns the formatted remote provider error
+// Error returns the formatted remote provider error.
func (rce RemoteConfigError) Error() string {
return fmt.Sprintf("Remote Configurations Error: %s", string(rce))
}
@@ -125,7 +127,7 @@ func (faee ConfigFileAlreadyExistsError) Error() string {
}
// A DecoderConfigOption can be passed to viper.Unmarshal to configure
-// mapstructure.DecoderConfig options
+// mapstructure.DecoderConfig options.
type DecoderConfigOption func(*mapstructure.DecoderConfig)
// DecodeHook returns a DecoderConfigOption which overrides the default
@@ -206,10 +208,10 @@ type Viper struct {
allowEmptyEnv bool
parents []string
- config map[string]interface{}
- override map[string]interface{}
- defaults map[string]interface{}
- kvstore map[string]interface{}
+ config map[string]any
+ override map[string]any
+ defaults map[string]any
+ kvstore map[string]any
pflags map[string]FlagValue
env map[string][]string
aliases map[string]string
@@ -217,7 +219,7 @@ type Viper struct {
onConfigChange func(fsnotify.Event)
- logger Logger
+ logger *slog.Logger
// TODO: should probably be protected with a mutex
encoderRegistry *encoding.EncoderRegistry
@@ -231,16 +233,16 @@ func New() *Viper {
v.configName = "config"
v.configPermissions = os.FileMode(0o644)
v.fs = afero.NewOsFs()
- v.config = make(map[string]interface{})
+ v.config = make(map[string]any)
v.parents = []string{}
- v.override = make(map[string]interface{})
- v.defaults = make(map[string]interface{})
- v.kvstore = make(map[string]interface{})
+ v.override = make(map[string]any)
+ v.defaults = make(map[string]any)
+ v.kvstore = make(map[string]any)
v.pflags = make(map[string]FlagValue)
v.env = make(map[string][]string)
v.aliases = make(map[string]string)
v.typeByDefValue = false
- v.logger = jwwLogger{}
+ v.logger = slog.New(&discardHandler{})
v.resetEncoding()
@@ -301,10 +303,10 @@ func NewWithOptions(opts ...Option) *Viper {
func Reset() {
v = New()
SupportedExts = []string{"json", "toml", "yaml", "yml", "properties", "props", "prop", "hcl", "tfvars", "dotenv", "env", "ini"}
- SupportedRemoteProviders = []string{"etcd", "etcd3", "consul", "firestore"}
+ SupportedRemoteProviders = []string{"etcd", "etcd3", "consul", "firestore", "nats"}
}
-// TODO: make this lazy initialization instead
+// TODO: make this lazy initialization instead.
func (v *Viper) resetEncoding() {
encoderRegistry := encoding.NewEncoderRegistry()
decoderRegistry := encoding.NewDecoderRegistry()
@@ -420,7 +422,7 @@ type RemoteProvider interface {
var SupportedExts = []string{"json", "toml", "yaml", "yml", "properties", "props", "prop", "hcl", "tfvars", "dotenv", "env", "ini"}
// SupportedRemoteProviders are universally supported remote providers.
-var SupportedRemoteProviders = []string{"etcd", "etcd3", "consul", "firestore"}
+var SupportedRemoteProviders = []string{"etcd", "etcd3", "consul", "firestore", "nats"}
// OnConfigChange sets the event handler that is called when a config file changes.
func OnConfigChange(run func(in fsnotify.Event)) { v.OnConfigChange(run) }
@@ -438,7 +440,7 @@ func (v *Viper) WatchConfig() {
initWG := sync.WaitGroup{}
initWG.Add(1)
go func() {
- watcher, err := newWatcher()
+ watcher, err := fsnotify.NewWatcher()
if err != nil {
v.logger.Error(fmt.Sprintf("failed to create watcher: %s", err))
os.Exit(1)
@@ -523,6 +525,12 @@ func (v *Viper) SetEnvPrefix(in string) {
}
}
+func GetEnvPrefix() string { return v.GetEnvPrefix() }
+
+func (v *Viper) GetEnvPrefix() string {
+ return v.envPrefix
+}
+
func (v *Viper) mergeWithEnvPrefix(in string) string {
if v.envPrefix != "" {
return strings.ToUpper(v.envPrefix + "_" + in)
@@ -578,12 +586,12 @@ func (v *Viper) AddConfigPath(in string) {
// AddRemoteProvider adds a remote configuration source.
// Remote Providers are searched in the order they are added.
-// provider is a string value: "etcd", "etcd3", "consul" or "firestore" are currently supported.
-// endpoint is the url. etcd requires http://ip:port consul requires ip:port
+// provider is a string value: "etcd", "etcd3", "consul", "firestore" or "nats" are currently supported.
+// endpoint is the url. etcd requires http://ip:port, consul requires ip:port, nats requires nats://ip:port
// path is the path in the k/v store to retrieve configuration
// To retrieve a config file called myapp.json from /configs/myapp.json
// you should set path to /configs and set config name (SetConfigName()) to
-// "myapp"
+// "myapp".
func AddRemoteProvider(provider, endpoint, path string) error {
return v.AddRemoteProvider(provider, endpoint, path)
}
@@ -609,14 +617,14 @@ func (v *Viper) AddRemoteProvider(provider, endpoint, path string) error {
// AddSecureRemoteProvider adds a remote configuration source.
// Secure Remote Providers are searched in the order they are added.
-// provider is a string value: "etcd", "etcd3", "consul" or "firestore" are currently supported.
+// provider is a string value: "etcd", "etcd3", "consul", "firestore" or "nats" are currently supported.
// endpoint is the url. etcd requires http://ip:port consul requires ip:port
// secretkeyring is the filepath to your openpgp secret keyring. e.g. /etc/secrets/myring.gpg
// path is the path in the k/v store to retrieve configuration
// To retrieve a config file called myapp.json from /configs/myapp.json
// you should set path to /configs and set config name (SetConfigName()) to
-// "myapp"
-// Secure Remote Providers are implemented with github.com/bketelsen/crypt
+// "myapp".
+// Secure Remote Providers are implemented with github.com/bketelsen/crypt.
func AddSecureRemoteProvider(provider, endpoint, path, secretkeyring string) error {
return v.AddSecureRemoteProvider(provider, endpoint, path, secretkeyring)
}
@@ -653,7 +661,7 @@ func (v *Viper) providerPathExists(p *defaultRemoteProvider) bool {
// searchMap recursively searches for a value for path in source map.
// Returns nil if not found.
// Note: This assumes that the path entries and map keys are lower cased.
-func (v *Viper) searchMap(source map[string]interface{}, path []string) interface{} {
+func (v *Viper) searchMap(source map[string]any, path []string) any {
if len(path) == 0 {
return source
}
@@ -666,13 +674,13 @@ func (v *Viper) searchMap(source map[string]interface{}, path []string) interfac
}
// Nested case
- switch next.(type) {
- case map[interface{}]interface{}:
+ switch next := next.(type) {
+ case map[any]any:
return v.searchMap(cast.ToStringMap(next), path[1:])
- case map[string]interface{}:
+ case map[string]any:
// Type assertion is safe here since it is only reached
// if the type of `next` is the same as the type being asserted
- return v.searchMap(next.(map[string]interface{}), path[1:])
+ return v.searchMap(next, path[1:])
default:
// got a value but nested key expected, return "nil" for not found
return nil
@@ -692,7 +700,7 @@ func (v *Viper) searchMap(source map[string]interface{}, path []string) interfac
// in their keys).
//
// Note: This assumes that the path entries and map keys are lower cased.
-func (v *Viper) searchIndexableWithPathPrefixes(source interface{}, path []string) interface{} {
+func (v *Viper) searchIndexableWithPathPrefixes(source any, path []string) any {
if len(path) == 0 {
return source
}
@@ -701,11 +709,11 @@ func (v *Viper) searchIndexableWithPathPrefixes(source interface{}, path []strin
for i := len(path); i > 0; i-- {
prefixKey := strings.ToLower(strings.Join(path[0:i], v.keyDelim))
- var val interface{}
+ var val any
switch sourceIndexable := source.(type) {
- case []interface{}:
+ case []any:
val = v.searchSliceWithPathPrefixes(sourceIndexable, prefixKey, i, path)
- case map[string]interface{}:
+ case map[string]any:
val = v.searchMapWithPathPrefixes(sourceIndexable, prefixKey, i, path)
}
if val != nil {
@@ -722,11 +730,11 @@ func (v *Viper) searchIndexableWithPathPrefixes(source interface{}, path []strin
// This function is part of the searchIndexableWithPathPrefixes recurring search and
// should not be called directly from functions other than searchIndexableWithPathPrefixes.
func (v *Viper) searchSliceWithPathPrefixes(
- sourceSlice []interface{},
+ sourceSlice []any,
prefixKey string,
pathIndex int,
path []string,
-) interface{} {
+) any {
// if the prefixKey is not a number or it is out of bounds of the slice
index, err := strconv.Atoi(prefixKey)
if err != nil || len(sourceSlice) <= index {
@@ -741,9 +749,9 @@ func (v *Viper) searchSliceWithPathPrefixes(
}
switch n := next.(type) {
- case map[interface{}]interface{}:
+ case map[any]any:
return v.searchIndexableWithPathPrefixes(cast.ToStringMap(n), path[pathIndex:])
- case map[string]interface{}, []interface{}:
+ case map[string]any, []any:
return v.searchIndexableWithPathPrefixes(n, path[pathIndex:])
default:
// got a value but nested key expected, do nothing and look for next prefix
@@ -758,11 +766,11 @@ func (v *Viper) searchSliceWithPathPrefixes(
// This function is part of the searchIndexableWithPathPrefixes recurring search and
// should not be called directly from functions other than searchIndexableWithPathPrefixes.
func (v *Viper) searchMapWithPathPrefixes(
- sourceMap map[string]interface{},
+ sourceMap map[string]any,
prefixKey string,
pathIndex int,
path []string,
-) interface{} {
+) any {
next, ok := sourceMap[prefixKey]
if !ok {
return nil
@@ -775,9 +783,9 @@ func (v *Viper) searchMapWithPathPrefixes(
// Nested case
switch n := next.(type) {
- case map[interface{}]interface{}:
+ case map[any]any:
return v.searchIndexableWithPathPrefixes(cast.ToStringMap(n), path[pathIndex:])
- case map[string]interface{}, []interface{}:
+ case map[string]any, []any:
return v.searchIndexableWithPathPrefixes(n, path[pathIndex:])
default:
// got a value but nested key expected, do nothing and look for next prefix
@@ -792,8 +800,8 @@ func (v *Viper) searchMapWithPathPrefixes(
// e.g., if "foo.bar" has a value in the given map, it “shadows”
//
// "foo.bar.baz" in a lower-priority map
-func (v *Viper) isPathShadowedInDeepMap(path []string, m map[string]interface{}) string {
- var parentVal interface{}
+func (v *Viper) isPathShadowedInDeepMap(path []string, m map[string]any) string {
+ var parentVal any
for i := 1; i < len(path); i++ {
parentVal = v.searchMap(m, path[0:i])
if parentVal == nil {
@@ -801,9 +809,9 @@ func (v *Viper) isPathShadowedInDeepMap(path []string, m map[string]interface{})
return ""
}
switch parentVal.(type) {
- case map[interface{}]interface{}:
+ case map[any]any:
continue
- case map[string]interface{}:
+ case map[string]any:
continue
default:
// parentVal is a regular value which shadows "path"
@@ -818,12 +826,14 @@ func (v *Viper) isPathShadowedInDeepMap(path []string, m map[string]interface{})
// e.g., if "foo.bar" has a value in the given map, it “shadows”
//
// "foo.bar.baz" in a lower-priority map
-func (v *Viper) isPathShadowedInFlatMap(path []string, mi interface{}) string {
+func (v *Viper) isPathShadowedInFlatMap(path []string, mi any) string {
// unify input map
var m map[string]interface{}
- switch mi.(type) {
- case map[string]string, map[string]FlagValue:
- m = cast.ToStringMap(mi)
+ switch miv := mi.(type) {
+ case map[string]string:
+ m = castMapStringToMapInterface(miv)
+ case map[string]FlagValue:
+ m = castMapFlagToMapInterface(miv)
default:
return ""
}
@@ -887,9 +897,9 @@ func GetViper() *Viper {
// override, flag, env, config file, key/value store, default
//
// Get returns an interface. For a specific value use one of the Get____ methods.
-func Get(key string) interface{} { return v.Get(key) }
+func Get(key string) any { return v.Get(key) }
-func (v *Viper) Get(key string) interface{} {
+func (v *Viper) Get(key string) any {
lcaseKey := strings.ToLower(key)
val := v.find(lcaseKey, true)
if val == nil {
@@ -950,7 +960,8 @@ func (v *Viper) Sub(key string) *Viper {
}
if reflect.TypeOf(data).Kind() == reflect.Map {
- subv.parents = append(v.parents, strings.ToLower(key))
+ subv.parents = append([]string(nil), v.parents...)
+ subv.parents = append(subv.parents, strings.ToLower(key))
subv.automaticEnvApplied = v.automaticEnvApplied
subv.envPrefix = v.envPrefix
subv.envKeyReplacer = v.envKeyReplacer
@@ -1059,9 +1070,9 @@ func (v *Viper) GetStringSlice(key string) []string {
}
// GetStringMap returns the value associated with the key as a map of interfaces.
-func GetStringMap(key string) map[string]interface{} { return v.GetStringMap(key) }
+func GetStringMap(key string) map[string]any { return v.GetStringMap(key) }
-func (v *Viper) GetStringMap(key string) map[string]interface{} {
+func (v *Viper) GetStringMap(key string) map[string]any {
return cast.ToStringMap(v.Get(key))
}
@@ -1089,27 +1100,58 @@ func (v *Viper) GetSizeInBytes(key string) uint {
}
// UnmarshalKey takes a single key and unmarshals it into a Struct.
-func UnmarshalKey(key string, rawVal interface{}, opts ...DecoderConfigOption) error {
+func UnmarshalKey(key string, rawVal any, opts ...DecoderConfigOption) error {
return v.UnmarshalKey(key, rawVal, opts...)
}
-func (v *Viper) UnmarshalKey(key string, rawVal interface{}, opts ...DecoderConfigOption) error {
+func (v *Viper) UnmarshalKey(key string, rawVal any, opts ...DecoderConfigOption) error {
return decode(v.Get(key), defaultDecoderConfig(rawVal, opts...))
}
// Unmarshal unmarshals the config into a Struct. Make sure that the tags
// on the fields of the structure are properly set.
-func Unmarshal(rawVal interface{}, opts ...DecoderConfigOption) error {
+func Unmarshal(rawVal any, opts ...DecoderConfigOption) error {
return v.Unmarshal(rawVal, opts...)
}
-func (v *Viper) Unmarshal(rawVal interface{}, opts ...DecoderConfigOption) error {
- return decode(v.AllSettings(), defaultDecoderConfig(rawVal, opts...))
+func (v *Viper) Unmarshal(rawVal any, opts ...DecoderConfigOption) error {
+ keys := v.AllKeys()
+
+ if features.BindStruct {
+ // TODO: make this optional?
+ structKeys, err := v.decodeStructKeys(rawVal, opts...)
+ if err != nil {
+ return err
+ }
+
+ keys = append(keys, structKeys...)
+ }
+
+ // TODO: struct keys should be enough?
+ return decode(v.getSettings(keys), defaultDecoderConfig(rawVal, opts...))
+}
+
+func (v *Viper) decodeStructKeys(input any, opts ...DecoderConfigOption) ([]string, error) {
+ var structKeyMap map[string]any
+
+ err := decode(input, defaultDecoderConfig(&structKeyMap, opts...))
+ if err != nil {
+ return nil, err
+ }
+
+ flattenedStructKeyMap := v.flattenAndMergeMap(map[string]bool{}, structKeyMap, "")
+
+ r := make([]string, 0, len(flattenedStructKeyMap))
+ for v := range flattenedStructKeyMap {
+ r = append(r, v)
+ }
+
+ return r, nil
}
// defaultDecoderConfig returns default mapstructure.DecoderConfig with support
-// of time.Duration values & string slices
-func defaultDecoderConfig(output interface{}, opts ...DecoderConfigOption) *mapstructure.DecoderConfig {
+// of time.Duration values & string slices.
+func defaultDecoderConfig(output any, opts ...DecoderConfigOption) *mapstructure.DecoderConfig {
c := &mapstructure.DecoderConfig{
Metadata: nil,
Result: output,
@@ -1125,8 +1167,8 @@ func defaultDecoderConfig(output interface{}, opts ...DecoderConfigOption) *maps
return c
}
-// A wrapper around mapstructure.Decode that mimics the WeakDecode functionality
-func decode(input interface{}, config *mapstructure.DecoderConfig) error {
+// decode is a wrapper around mapstructure.Decode that mimics the WeakDecode functionality.
+func decode(input any, config *mapstructure.DecoderConfig) error {
decoder, err := mapstructure.NewDecoder(config)
if err != nil {
return err
@@ -1136,15 +1178,28 @@ func decode(input interface{}, config *mapstructure.DecoderConfig) error {
// UnmarshalExact unmarshals the config into a Struct, erroring if a field is nonexistent
// in the destination struct.
-func UnmarshalExact(rawVal interface{}, opts ...DecoderConfigOption) error {
+func UnmarshalExact(rawVal any, opts ...DecoderConfigOption) error {
return v.UnmarshalExact(rawVal, opts...)
}
-func (v *Viper) UnmarshalExact(rawVal interface{}, opts ...DecoderConfigOption) error {
+func (v *Viper) UnmarshalExact(rawVal any, opts ...DecoderConfigOption) error {
config := defaultDecoderConfig(rawVal, opts...)
config.ErrorUnused = true
- return decode(v.AllSettings(), config)
+ keys := v.AllKeys()
+
+ if features.BindStruct {
+ // TODO: make this optional?
+ structKeys, err := v.decodeStructKeys(rawVal, opts...)
+ if err != nil {
+ return err
+ }
+
+ keys = append(keys, structKeys...)
+ }
+
+ // TODO: struct keys should be enough?
+ return decode(v.getSettings(keys), config)
}
// BindPFlags binds a full flag set to the configuration, using each flag's long
@@ -1237,9 +1292,9 @@ func (v *Viper) MustBindEnv(input ...string) {
// corresponds to a flag, the flag's default value is returned.
//
// Note: this assumes a lower-cased key given.
-func (v *Viper) find(lcaseKey string, flagDefault bool) interface{} {
+func (v *Viper) find(lcaseKey string, flagDefault bool) any {
var (
- val interface{}
+ val any
exists bool
path = strings.Split(lcaseKey, v.keyDelim)
nested = len(path) > 1
@@ -1398,46 +1453,46 @@ func readAsCSV(val string) ([]string, error) {
}
// mostly copied from pflag's implementation of this operation here https://github.com/spf13/pflag/blob/master/string_to_string.go#L79
-// alterations are: errors are swallowed, map[string]interface{} is returned in order to enable cast.ToStringMap
-func stringToStringConv(val string) interface{} {
+// alterations are: errors are swallowed, map[string]any is returned in order to enable cast.ToStringMap.
+func stringToStringConv(val string) any {
val = strings.Trim(val, "[]")
// An empty string would cause an empty map
- if len(val) == 0 {
- return map[string]interface{}{}
+ if val == "" {
+ return map[string]any{}
}
r := csv.NewReader(strings.NewReader(val))
ss, err := r.Read()
if err != nil {
return nil
}
- out := make(map[string]interface{}, len(ss))
+ out := make(map[string]any, len(ss))
for _, pair := range ss {
- kv := strings.SplitN(pair, "=", 2)
- if len(kv) != 2 {
+ k, vv, found := strings.Cut(pair, "=")
+ if !found {
return nil
}
- out[kv[0]] = kv[1]
+ out[k] = vv
}
return out
}
// mostly copied from pflag's implementation of this operation here https://github.com/spf13/pflag/blob/d5e0c0615acee7028e1e2740a11102313be88de1/string_to_int.go#L68
-// alterations are: errors are swallowed, map[string]interface{} is returned in order to enable cast.ToStringMap
-func stringToIntConv(val string) interface{} {
+// alterations are: errors are swallowed, map[string]any is returned in order to enable cast.ToStringMap.
+func stringToIntConv(val string) any {
val = strings.Trim(val, "[]")
// An empty string would cause an empty map
- if len(val) == 0 {
- return map[string]interface{}{}
+ if val == "" {
+ return map[string]any{}
}
ss := strings.Split(val, ",")
- out := make(map[string]interface{}, len(ss))
+ out := make(map[string]any, len(ss))
for _, pair := range ss {
- kv := strings.SplitN(pair, "=", 2)
- if len(kv) != 2 {
+ k, vv, found := strings.Cut(pair, "=")
+ if !found {
return nil
}
var err error
- out[kv[0]], err = strconv.Atoi(kv[1])
+ out[k], err = strconv.Atoi(vv)
if err != nil {
return nil
}
@@ -1474,13 +1529,13 @@ func (v *Viper) SetEnvKeyReplacer(r *strings.Replacer) {
// RegisterAlias creates an alias that provides another accessor for the same key.
// This enables one to change a name without breaking the application.
-func RegisterAlias(alias string, key string) { v.RegisterAlias(alias, key) }
+func RegisterAlias(alias, key string) { v.RegisterAlias(alias, key) }
-func (v *Viper) RegisterAlias(alias string, key string) {
+func (v *Viper) RegisterAlias(alias, key string) {
v.registerAlias(alias, strings.ToLower(key))
}
-func (v *Viper) registerAlias(alias string, key string) {
+func (v *Viper) registerAlias(alias, key string) {
alias = strings.ToLower(alias)
if alias != key && alias != v.realKey(key) {
_, exists := v.aliases[alias]
@@ -1538,9 +1593,9 @@ func (v *Viper) InConfig(key string) bool {
// SetDefault sets the default value for this key.
// SetDefault is case-insensitive for a key.
// Default only used when no value is provided by the user via flag, config or ENV.
-func SetDefault(key string, value interface{}) { v.SetDefault(key, value) }
+func SetDefault(key string, value any) { v.SetDefault(key, value) }
-func (v *Viper) SetDefault(key string, value interface{}) {
+func (v *Viper) SetDefault(key string, value any) {
// If alias passed in, then set the proper default
key = v.realKey(strings.ToLower(key))
value = toCaseInsensitiveValue(value)
@@ -1557,9 +1612,9 @@ func (v *Viper) SetDefault(key string, value interface{}) {
// Set is case-insensitive for a key.
// Will be used instead of values obtained via
// flags, config file, ENV, default, or key/value store.
-func Set(key string, value interface{}) { v.Set(key, value) }
+func Set(key string, value any) { v.Set(key, value) }
-func (v *Viper) Set(key string, value interface{}) {
+func (v *Viper) Set(key string, value any) {
// If alias passed in, then set the proper override
key = v.realKey(strings.ToLower(key))
value = toCaseInsensitiveValue(value)
@@ -1593,7 +1648,7 @@ func (v *Viper) ReadInConfig() error {
return err
}
- config := make(map[string]interface{})
+ config := make(map[string]any)
err = v.unmarshalReader(bytes.NewReader(file), config)
if err != nil {
@@ -1631,7 +1686,7 @@ func (v *Viper) MergeInConfig() error {
func ReadConfig(in io.Reader) error { return v.ReadConfig(in) }
func (v *Viper) ReadConfig(in io.Reader) error {
- v.config = make(map[string]interface{})
+ v.config = make(map[string]any)
return v.unmarshalReader(in, v.config)
}
@@ -1639,7 +1694,7 @@ func (v *Viper) ReadConfig(in io.Reader) error {
func MergeConfig(in io.Reader) error { return v.MergeConfig(in) }
func (v *Viper) MergeConfig(in io.Reader) error {
- cfg := make(map[string]interface{})
+ cfg := make(map[string]any)
if err := v.unmarshalReader(in, cfg); err != nil {
return err
}
@@ -1648,11 +1703,11 @@ func (v *Viper) MergeConfig(in io.Reader) error {
// MergeConfigMap merges the configuration from the map given with an existing config.
// Note that the map given may be modified.
-func MergeConfigMap(cfg map[string]interface{}) error { return v.MergeConfigMap(cfg) }
+func MergeConfigMap(cfg map[string]any) error { return v.MergeConfigMap(cfg) }
-func (v *Viper) MergeConfigMap(cfg map[string]interface{}) error {
+func (v *Viper) MergeConfigMap(cfg map[string]any) error {
if v.config == nil {
- v.config = make(map[string]interface{})
+ v.config = make(map[string]any)
}
insensitiviseMap(cfg)
mergeMaps(cfg, v.config, nil)
@@ -1717,7 +1772,7 @@ func (v *Viper) writeConfig(filename string, force bool) error {
return UnsupportedConfigError(configType)
}
if v.config == nil {
- v.config = make(map[string]interface{})
+ v.config = make(map[string]any)
}
flags := os.O_CREATE | os.O_TRUNC | os.O_WRONLY
if !force {
@@ -1738,11 +1793,11 @@ func (v *Viper) writeConfig(filename string, force bool) error {
// Unmarshal a Reader into a map.
// Should probably be an unexported function.
-func unmarshalReader(in io.Reader, c map[string]interface{}) error {
+func unmarshalReader(in io.Reader, c map[string]any) error {
return v.unmarshalReader(in, c)
}
-func (v *Viper) unmarshalReader(in io.Reader, c map[string]interface{}) error {
+func (v *Viper) unmarshalReader(in io.Reader, c map[string]any) error {
buf := new(bytes.Buffer)
buf.ReadFrom(in)
@@ -1776,7 +1831,7 @@ func (v *Viper) marshalWriter(f afero.File, configType string) error {
return nil
}
-func keyExists(k string, m map[string]interface{}) string {
+func keyExists(k string, m map[string]any) string {
lk := strings.ToLower(k)
for mk := range m {
lmk := strings.ToLower(mk)
@@ -1788,33 +1843,33 @@ func keyExists(k string, m map[string]interface{}) string {
}
func castToMapStringInterface(
- src map[interface{}]interface{},
-) map[string]interface{} {
- tgt := map[string]interface{}{}
+ src map[any]any,
+) map[string]any {
+ tgt := map[string]any{}
for k, v := range src {
tgt[fmt.Sprintf("%v", k)] = v
}
return tgt
}
-func castMapStringSliceToMapInterface(src map[string][]string) map[string]interface{} {
- tgt := map[string]interface{}{}
+func castMapStringSliceToMapInterface(src map[string][]string) map[string]any {
+ tgt := map[string]any{}
for k, v := range src {
tgt[k] = v
}
return tgt
}
-func castMapStringToMapInterface(src map[string]string) map[string]interface{} {
- tgt := map[string]interface{}{}
+func castMapStringToMapInterface(src map[string]string) map[string]any {
+ tgt := map[string]any{}
for k, v := range src {
tgt[k] = v
}
return tgt
}
-func castMapFlagToMapInterface(src map[string]FlagValue) map[string]interface{} {
- tgt := map[string]interface{}{}
+func castMapFlagToMapInterface(src map[string]FlagValue) map[string]any {
+ tgt := map[string]any{}
for k, v := range src {
tgt[k] = v
}
@@ -1822,17 +1877,15 @@ func castMapFlagToMapInterface(src map[string]FlagValue) map[string]interface{}
}
// mergeMaps merges two maps. The `itgt` parameter is for handling go-yaml's
-// insistence on parsing nested structures as `map[interface{}]interface{}`
+// insistence on parsing nested structures as `map[any]any`
// instead of using a `string` as the key for nest structures beyond one level
// deep. Both map types are supported as there is a go-yaml fork that uses
-// `map[string]interface{}` instead.
-func mergeMaps(
- src, tgt map[string]interface{}, itgt map[interface{}]interface{},
-) {
+// `map[string]any` instead.
+func mergeMaps(src, tgt map[string]any, itgt map[any]any) {
for sk, sv := range src {
tk := keyExists(sk, tgt)
if tk == "" {
- v.logger.Trace("", "tk", "\"\"", fmt.Sprintf("tgt[%s]", sk), sv)
+ v.logger.Debug("", "tk", "\"\"", fmt.Sprintf("tgt[%s]", sk), sv)
tgt[sk] = sv
if itgt != nil {
itgt[sk] = sv
@@ -1842,7 +1895,7 @@ func mergeMaps(
tv, ok := tgt[tk]
if !ok {
- v.logger.Trace("", fmt.Sprintf("ok[%s]", tk), false, fmt.Sprintf("tgt[%s]", sk), sv)
+ v.logger.Debug("", fmt.Sprintf("ok[%s]", tk), false, fmt.Sprintf("tgt[%s]", sk), sv)
tgt[sk] = sv
if itgt != nil {
itgt[sk] = sv
@@ -1853,7 +1906,7 @@ func mergeMaps(
svType := reflect.TypeOf(sv)
tvType := reflect.TypeOf(tv)
- v.logger.Trace(
+ v.logger.Debug(
"processing",
"key", sk,
"st", svType,
@@ -1863,12 +1916,12 @@ func mergeMaps(
)
switch ttv := tv.(type) {
- case map[interface{}]interface{}:
- v.logger.Trace("merging maps (must convert)")
- tsv, ok := sv.(map[interface{}]interface{})
+ case map[any]any:
+ v.logger.Debug("merging maps (must convert)")
+ tsv, ok := sv.(map[any]any)
if !ok {
v.logger.Error(
- "Could not cast sv to map[interface{}]interface{}",
+ "Could not cast sv to map[any]any",
"key", sk,
"st", svType,
"tt", tvType,
@@ -1881,12 +1934,12 @@ func mergeMaps(
ssv := castToMapStringInterface(tsv)
stv := castToMapStringInterface(ttv)
mergeMaps(ssv, stv, ttv)
- case map[string]interface{}:
- v.logger.Trace("merging maps")
- tsv, ok := sv.(map[string]interface{})
+ case map[string]any:
+ v.logger.Debug("merging maps")
+ tsv, ok := sv.(map[string]any)
if !ok {
v.logger.Error(
- "Could not cast sv to map[string]interface{}",
+ "Could not cast sv to map[string]any",
"key", sk,
"st", svType,
"tt", tvType,
@@ -1897,7 +1950,7 @@ func mergeMaps(
}
mergeMaps(tsv, ttv, nil)
default:
- v.logger.Trace("setting value")
+ v.logger.Debug("setting value")
tgt[tk] = sv
if itgt != nil {
itgt[tk] = sv
@@ -1948,7 +2001,7 @@ func (v *Viper) getKeyValueConfig() error {
return RemoteConfigError("No Files Found")
}
-func (v *Viper) getRemoteConfig(provider RemoteProvider) (map[string]interface{}, error) {
+func (v *Viper) getRemoteConfig(provider RemoteProvider) (map[string]any, error) {
reader, err := RemoteConfig.Get(provider)
if err != nil {
return nil, err
@@ -1997,7 +2050,7 @@ func (v *Viper) watchKeyValueConfig() error {
return RemoteConfigError("No Files Found")
}
-func (v *Viper) watchRemoteConfig(provider RemoteProvider) (map[string]interface{}, error) {
+func (v *Viper) watchRemoteConfig(provider RemoteProvider) (map[string]any, error) {
reader, err := RemoteConfig.Watch(provider)
if err != nil {
return nil, err
@@ -2007,7 +2060,7 @@ func (v *Viper) watchRemoteConfig(provider RemoteProvider) (map[string]interface
}
// AllKeys returns all keys holding a value, regardless of where they are set.
-// Nested keys are returned with a v.keyDelim separator
+// Nested keys are returned with a v.keyDelim separator.
func AllKeys() []string { return v.AllKeys() }
func (v *Viper) AllKeys() []string {
@@ -2036,7 +2089,7 @@ func (v *Viper) AllKeys() []string {
// it is skipped.
//
// The resulting set of paths is merged to the given shadow set at the same time.
-func (v *Viper) flattenAndMergeMap(shadow map[string]bool, m map[string]interface{}, prefix string) map[string]bool {
+func (v *Viper) flattenAndMergeMap(shadow map[string]bool, m map[string]any, prefix string) map[string]bool {
if shadow != nil && prefix != "" && shadow[prefix] {
// prefix is shadowed => nothing more to flatten
return shadow
@@ -2045,16 +2098,16 @@ func (v *Viper) flattenAndMergeMap(shadow map[string]bool, m map[string]interfac
shadow = make(map[string]bool)
}
- var m2 map[string]interface{}
+ var m2 map[string]any
if prefix != "" {
prefix += v.keyDelim
}
for k, val := range m {
fullKey := prefix + k
- switch val.(type) {
- case map[string]interface{}:
- m2 = val.(map[string]interface{})
- case map[interface{}]interface{}:
+ switch val := val.(type) {
+ case map[string]any:
+ m2 = val
+ case map[any]any:
m2 = cast.ToStringMap(val)
default:
// immediate value
@@ -2069,7 +2122,7 @@ func (v *Viper) flattenAndMergeMap(shadow map[string]bool, m map[string]interfac
// mergeFlatMap merges the given maps, excluding values of the second map
// shadowed by values from the first map.
-func (v *Viper) mergeFlatMap(shadow map[string]bool, m map[string]interface{}) map[string]bool {
+func (v *Viper) mergeFlatMap(shadow map[string]bool, m map[string]any) map[string]bool {
// scan keys
outer:
for k := range m {
@@ -2089,13 +2142,17 @@ outer:
return shadow
}
-// AllSettings merges all settings and returns them as a map[string]interface{}.
-func AllSettings() map[string]interface{} { return v.AllSettings() }
+// AllSettings merges all settings and returns them as a map[string]any.
+func AllSettings() map[string]any { return v.AllSettings() }
-func (v *Viper) AllSettings() map[string]interface{} {
- m := map[string]interface{}{}
+func (v *Viper) AllSettings() map[string]any {
+ return v.getSettings(v.AllKeys())
+}
+
+func (v *Viper) getSettings(keys []string) map[string]any {
+ m := map[string]any{}
// start from the list of keys, and construct the map one value at a time
- for _, k := range v.AllKeys() {
+ for _, k := range keys {
value := v.Get(k)
if value == nil {
// should not happen, since AllKeys() returns only keys holding a value,
diff --git a/vendor/github.com/spf13/viper/viper_go1_16.go b/vendor/github.com/spf13/viper/viper_go1_16.go
deleted file mode 100644
index e10172fa3..000000000
--- a/vendor/github.com/spf13/viper/viper_go1_16.go
+++ /dev/null
@@ -1,32 +0,0 @@
-//go:build go1.16 && finder
-// +build go1.16,finder
-
-package viper
-
-import (
- "fmt"
-
- "github.com/spf13/afero"
-)
-
-// Search all configPaths for any config file.
-// Returns the first path that exists (and is a config file).
-func (v *Viper) findConfigFile() (string, error) {
- finder := finder{
- paths: v.configPaths,
- fileNames: []string{v.configName},
- extensions: SupportedExts,
- withoutExtension: v.configType != "",
- }
-
- file, err := finder.Find(afero.NewIOFS(v.fs))
- if err != nil {
- return "", err
- }
-
- if file == "" {
- return "", ConfigFileNotFoundError{v.configName, fmt.Sprintf("%s", v.configPaths)}
- }
-
- return file, nil
-}
diff --git a/vendor/github.com/spf13/viper/watch.go b/vendor/github.com/spf13/viper/watch.go
deleted file mode 100644
index 1ce84eaf8..000000000
--- a/vendor/github.com/spf13/viper/watch.go
+++ /dev/null
@@ -1,12 +0,0 @@
-//go:build darwin || dragonfly || freebsd || openbsd || linux || netbsd || solaris || windows
-// +build darwin dragonfly freebsd openbsd linux netbsd solaris windows
-
-package viper
-
-import "github.com/fsnotify/fsnotify"
-
-type watcher = fsnotify.Watcher
-
-func newWatcher() (*watcher, error) {
- return fsnotify.NewWatcher()
-}
diff --git a/vendor/github.com/spf13/viper/watch_unsupported.go b/vendor/github.com/spf13/viper/watch_unsupported.go
deleted file mode 100644
index 7e2715377..000000000
--- a/vendor/github.com/spf13/viper/watch_unsupported.go
+++ /dev/null
@@ -1,32 +0,0 @@
-//go:build appengine || (!darwin && !dragonfly && !freebsd && !openbsd && !linux && !netbsd && !solaris && !windows)
-// +build appengine !darwin,!dragonfly,!freebsd,!openbsd,!linux,!netbsd,!solaris,!windows
-
-package viper
-
-import (
- "fmt"
- "runtime"
-
- "github.com/fsnotify/fsnotify"
-)
-
-func newWatcher() (*watcher, error) {
- return &watcher{}, fmt.Errorf("fsnotify not supported on %s", runtime.GOOS)
-}
-
-type watcher struct {
- Events chan fsnotify.Event
- Errors chan error
-}
-
-func (*watcher) Close() error {
- return nil
-}
-
-func (*watcher) Add(name string) error {
- return nil
-}
-
-func (*watcher) Remove(name string) error {
- return nil
-}
diff --git a/vendor/github.com/subosito/gotenv/CHANGELOG.md b/vendor/github.com/subosito/gotenv/CHANGELOG.md
index 757caad26..c4fe7d326 100644
--- a/vendor/github.com/subosito/gotenv/CHANGELOG.md
+++ b/vendor/github.com/subosito/gotenv/CHANGELOG.md
@@ -1,5 +1,42 @@
# Changelog
+## [1.5.0] - 2023-08-15
+
+### Fixed
+
+- Use io.Reader instead of custom Reader
+
+## [1.5.0] - 2023-08-15
+
+### Added
+
+- Support for reading UTF16 files
+
+### Fixed
+
+- Scanner error handling
+- Reader error handling
+
+## [1.4.2] - 2023-01-11
+
+### Fixed
+
+- Env var initialization
+
+### Changed
+
+- More consitent line splitting
+
+## [1.4.1] - 2022-08-23
+
+### Fixed
+
+- Missing file close
+
+### Changed
+
+- Updated dependencies
+
## [1.4.0] - 2022-06-02
### Added
diff --git a/vendor/github.com/subosito/gotenv/gotenv.go b/vendor/github.com/subosito/gotenv/gotenv.go
index dc013e1e0..1191d3587 100644
--- a/vendor/github.com/subosito/gotenv/gotenv.go
+++ b/vendor/github.com/subosito/gotenv/gotenv.go
@@ -12,6 +12,9 @@ import (
"sort"
"strconv"
"strings"
+
+ "golang.org/x/text/encoding/unicode"
+ "golang.org/x/text/transform"
)
const (
@@ -20,9 +23,13 @@ const (
// Pattern for detecting valid variable within a value
variablePattern = `(\\)?(\$)(\{?([A-Z0-9_]+)?\}?)`
+)
- // Byte order mark character
- bom = "\xef\xbb\xbf"
+// Byte order mark character
+var (
+ bomUTF8 = []byte("\xEF\xBB\xBF")
+ bomUTF16LE = []byte("\xFF\xFE")
+ bomUTF16BE = []byte("\xFE\xFF")
)
// Env holds key/value pair of valid environment variable
@@ -203,19 +210,40 @@ func splitLines(data []byte, atEOF bool) (advance int, token []byte, err error)
func strictParse(r io.Reader, override bool) (Env, error) {
env := make(Env)
- scanner := bufio.NewScanner(r)
+
+ buf := new(bytes.Buffer)
+ tee := io.TeeReader(r, buf)
+
+ // There can be a maximum of 3 BOM bytes.
+ bomByteBuffer := make([]byte, 3)
+ _, err := tee.Read(bomByteBuffer)
+ if err != nil && err != io.EOF {
+ return env, err
+ }
+
+ z := io.MultiReader(buf, r)
+
+ // We chooes a different scanner depending on file encoding.
+ var scanner *bufio.Scanner
+
+ if bytes.HasPrefix(bomByteBuffer, bomUTF8) {
+ scanner = bufio.NewScanner(transform.NewReader(z, unicode.UTF8BOM.NewDecoder()))
+ } else if bytes.HasPrefix(bomByteBuffer, bomUTF16LE) {
+ scanner = bufio.NewScanner(transform.NewReader(z, unicode.UTF16(unicode.LittleEndian, unicode.ExpectBOM).NewDecoder()))
+ } else if bytes.HasPrefix(bomByteBuffer, bomUTF16BE) {
+ scanner = bufio.NewScanner(transform.NewReader(z, unicode.UTF16(unicode.BigEndian, unicode.ExpectBOM).NewDecoder()))
+ } else {
+ scanner = bufio.NewScanner(z)
+ }
+
scanner.Split(splitLines)
- firstLine := true
-
for scanner.Scan() {
- line := strings.TrimSpace(scanner.Text())
-
- if firstLine {
- line = strings.TrimPrefix(line, bom)
- firstLine = false
+ if err := scanner.Err(); err != nil {
+ return env, err
}
+ line := strings.TrimSpace(scanner.Text())
if line == "" || line[0] == '#' {
continue
}
@@ -263,7 +291,7 @@ func strictParse(r io.Reader, override bool) (Env, error) {
}
}
- return env, nil
+ return env, scanner.Err()
}
var (
diff --git a/vendor/go.uber.org/multierr/.codecov.yml b/vendor/go.uber.org/multierr/.codecov.yml
new file mode 100644
index 000000000..6d4d1be7b
--- /dev/null
+++ b/vendor/go.uber.org/multierr/.codecov.yml
@@ -0,0 +1,15 @@
+coverage:
+ range: 80..100
+ round: down
+ precision: 2
+
+ status:
+ project: # measuring the overall project coverage
+ default: # context, you can create multiple ones with custom titles
+ enabled: yes # must be yes|true to enable this status
+ target: 100 # specify the target coverage for each commit status
+ # option: "auto" (must increase from parent commit or pull request base)
+ # option: "X%" a static target percentage to hit
+ if_not_found: success # if parent is not found report status as success, error, or failure
+ if_ci_failed: error # if ci fails report status as success, error, or failure
+
diff --git a/vendor/go.uber.org/multierr/.gitignore b/vendor/go.uber.org/multierr/.gitignore
new file mode 100644
index 000000000..b9a05e3da
--- /dev/null
+++ b/vendor/go.uber.org/multierr/.gitignore
@@ -0,0 +1,4 @@
+/vendor
+cover.html
+cover.out
+/bin
diff --git a/vendor/go.uber.org/multierr/CHANGELOG.md b/vendor/go.uber.org/multierr/CHANGELOG.md
new file mode 100644
index 000000000..f8177b978
--- /dev/null
+++ b/vendor/go.uber.org/multierr/CHANGELOG.md
@@ -0,0 +1,95 @@
+Releases
+========
+
+v1.11.0 (2023-03-28)
+====================
+- `Errors` now supports any error that implements multiple-error
+ interface.
+- Add `Every` function to allow checking if all errors in the chain
+ satisfies `errors.Is` against the target error.
+
+v1.10.0 (2023-03-08)
+====================
+
+- Comply with Go 1.20's multiple-error interface.
+- Drop Go 1.18 support.
+ Per the support policy, only Go 1.19 and 1.20 are supported now.
+- Drop all non-test external dependencies.
+
+v1.9.0 (2022-12-12)
+===================
+
+- Add `AppendFunc` that allow passsing functions to similar to
+ `AppendInvoke`.
+
+- Bump up yaml.v3 dependency to 3.0.1.
+
+v1.8.0 (2022-02-28)
+===================
+
+- `Combine`: perform zero allocations when there are no errors.
+
+
+v1.7.0 (2021-05-06)
+===================
+
+- Add `AppendInvoke` to append into errors from `defer` blocks.
+
+
+v1.6.0 (2020-09-14)
+===================
+
+- Actually drop library dependency on development-time tooling.
+
+
+v1.5.0 (2020-02-24)
+===================
+
+- Drop library dependency on development-time tooling.
+
+
+v1.4.0 (2019-11-04)
+===================
+
+- Add `AppendInto` function to more ergonomically build errors inside a
+ loop.
+
+
+v1.3.0 (2019-10-29)
+===================
+
+- Switch to Go modules.
+
+
+v1.2.0 (2019-09-26)
+===================
+
+- Support extracting and matching against wrapped errors with `errors.As`
+ and `errors.Is`.
+
+
+v1.1.0 (2017-06-30)
+===================
+
+- Added an `Errors(error) []error` function to extract the underlying list of
+ errors for a multierr error.
+
+
+v1.0.0 (2017-05-31)
+===================
+
+No changes since v0.2.0. This release is committing to making no breaking
+changes to the current API in the 1.X series.
+
+
+v0.2.0 (2017-04-11)
+===================
+
+- Repeatedly appending to the same error is now faster due to fewer
+ allocations.
+
+
+v0.1.0 (2017-31-03)
+===================
+
+- Initial release
diff --git a/vendor/go.uber.org/multierr/LICENSE.txt b/vendor/go.uber.org/multierr/LICENSE.txt
new file mode 100644
index 000000000..413e30f7c
--- /dev/null
+++ b/vendor/go.uber.org/multierr/LICENSE.txt
@@ -0,0 +1,19 @@
+Copyright (c) 2017-2021 Uber Technologies, Inc.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/vendor/go.uber.org/multierr/Makefile b/vendor/go.uber.org/multierr/Makefile
new file mode 100644
index 000000000..dcb6fe723
--- /dev/null
+++ b/vendor/go.uber.org/multierr/Makefile
@@ -0,0 +1,38 @@
+# Directory to put `go install`ed binaries in.
+export GOBIN ?= $(shell pwd)/bin
+
+GO_FILES := $(shell \
+ find . '(' -path '*/.*' -o -path './vendor' ')' -prune \
+ -o -name '*.go' -print | cut -b3-)
+
+.PHONY: build
+build:
+ go build ./...
+
+.PHONY: test
+test:
+ go test -race ./...
+
+.PHONY: gofmt
+gofmt:
+ $(eval FMT_LOG := $(shell mktemp -t gofmt.XXXXX))
+ @gofmt -e -s -l $(GO_FILES) > $(FMT_LOG) || true
+ @[ ! -s "$(FMT_LOG)" ] || (echo "gofmt failed:" | cat - $(FMT_LOG) && false)
+
+.PHONY: golint
+golint:
+ @cd tools && go install golang.org/x/lint/golint
+ @$(GOBIN)/golint ./...
+
+.PHONY: staticcheck
+staticcheck:
+ @cd tools && go install honnef.co/go/tools/cmd/staticcheck
+ @$(GOBIN)/staticcheck ./...
+
+.PHONY: lint
+lint: gofmt golint staticcheck
+
+.PHONY: cover
+cover:
+ go test -race -coverprofile=cover.out -coverpkg=./... -v ./...
+ go tool cover -html=cover.out -o cover.html
diff --git a/vendor/go.uber.org/multierr/README.md b/vendor/go.uber.org/multierr/README.md
new file mode 100644
index 000000000..5ab6ac40f
--- /dev/null
+++ b/vendor/go.uber.org/multierr/README.md
@@ -0,0 +1,43 @@
+# multierr [![GoDoc][doc-img]][doc] [![Build Status][ci-img]][ci] [![Coverage Status][cov-img]][cov]
+
+`multierr` allows combining one or more Go `error`s together.
+
+## Features
+
+- **Idiomatic**:
+ multierr follows best practices in Go, and keeps your code idiomatic.
+ - It keeps the underlying error type hidden,
+ allowing you to deal in `error` values exclusively.
+ - It provides APIs to safely append into an error from a `defer` statement.
+- **Performant**:
+ multierr is optimized for performance:
+ - It avoids allocations where possible.
+ - It utilizes slice resizing semantics to optimize common cases
+ like appending into the same error object from a loop.
+- **Interoperable**:
+ multierr interoperates with the Go standard library's error APIs seamlessly:
+ - The `errors.Is` and `errors.As` functions *just work*.
+- **Lightweight**:
+ multierr comes with virtually no dependencies.
+
+## Installation
+
+```bash
+go get -u go.uber.org/multierr@latest
+```
+
+## Status
+
+Stable: No breaking changes will be made before 2.0.
+
+-------------------------------------------------------------------------------
+
+Released under the [MIT License].
+
+[MIT License]: LICENSE.txt
+[doc-img]: https://pkg.go.dev/badge/go.uber.org/multierr
+[doc]: https://pkg.go.dev/go.uber.org/multierr
+[ci-img]: https://github.com/uber-go/multierr/actions/workflows/go.yml/badge.svg
+[cov-img]: https://codecov.io/gh/uber-go/multierr/branch/master/graph/badge.svg
+[ci]: https://github.com/uber-go/multierr/actions/workflows/go.yml
+[cov]: https://codecov.io/gh/uber-go/multierr
diff --git a/vendor/go.uber.org/multierr/error.go b/vendor/go.uber.org/multierr/error.go
new file mode 100644
index 000000000..3a828b2df
--- /dev/null
+++ b/vendor/go.uber.org/multierr/error.go
@@ -0,0 +1,646 @@
+// Copyright (c) 2017-2023 Uber Technologies, Inc.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+// Package multierr allows combining one or more errors together.
+//
+// # Overview
+//
+// Errors can be combined with the use of the Combine function.
+//
+// multierr.Combine(
+// reader.Close(),
+// writer.Close(),
+// conn.Close(),
+// )
+//
+// If only two errors are being combined, the Append function may be used
+// instead.
+//
+// err = multierr.Append(reader.Close(), writer.Close())
+//
+// The underlying list of errors for a returned error object may be retrieved
+// with the Errors function.
+//
+// errors := multierr.Errors(err)
+// if len(errors) > 0 {
+// fmt.Println("The following errors occurred:", errors)
+// }
+//
+// # Appending from a loop
+//
+// You sometimes need to append into an error from a loop.
+//
+// var err error
+// for _, item := range items {
+// err = multierr.Append(err, process(item))
+// }
+//
+// Cases like this may require knowledge of whether an individual instance
+// failed. This usually requires introduction of a new variable.
+//
+// var err error
+// for _, item := range items {
+// if perr := process(item); perr != nil {
+// log.Warn("skipping item", item)
+// err = multierr.Append(err, perr)
+// }
+// }
+//
+// multierr includes AppendInto to simplify cases like this.
+//
+// var err error
+// for _, item := range items {
+// if multierr.AppendInto(&err, process(item)) {
+// log.Warn("skipping item", item)
+// }
+// }
+//
+// This will append the error into the err variable, and return true if that
+// individual error was non-nil.
+//
+// See [AppendInto] for more information.
+//
+// # Deferred Functions
+//
+// Go makes it possible to modify the return value of a function in a defer
+// block if the function was using named returns. This makes it possible to
+// record resource cleanup failures from deferred blocks.
+//
+// func sendRequest(req Request) (err error) {
+// conn, err := openConnection()
+// if err != nil {
+// return err
+// }
+// defer func() {
+// err = multierr.Append(err, conn.Close())
+// }()
+// // ...
+// }
+//
+// multierr provides the Invoker type and AppendInvoke function to make cases
+// like the above simpler and obviate the need for a closure. The following is
+// roughly equivalent to the example above.
+//
+// func sendRequest(req Request) (err error) {
+// conn, err := openConnection()
+// if err != nil {
+// return err
+// }
+// defer multierr.AppendInvoke(&err, multierr.Close(conn))
+// // ...
+// }
+//
+// See [AppendInvoke] and [Invoker] for more information.
+//
+// NOTE: If you're modifying an error from inside a defer, you MUST use a named
+// return value for that function.
+//
+// # Advanced Usage
+//
+// Errors returned by Combine and Append MAY implement the following
+// interface.
+//
+// type errorGroup interface {
+// // Returns a slice containing the underlying list of errors.
+// //
+// // This slice MUST NOT be modified by the caller.
+// Errors() []error
+// }
+//
+// Note that if you need access to list of errors behind a multierr error, you
+// should prefer using the Errors function. That said, if you need cheap
+// read-only access to the underlying errors slice, you can attempt to cast
+// the error to this interface. You MUST handle the failure case gracefully
+// because errors returned by Combine and Append are not guaranteed to
+// implement this interface.
+//
+// var errors []error
+// group, ok := err.(errorGroup)
+// if ok {
+// errors = group.Errors()
+// } else {
+// errors = []error{err}
+// }
+package multierr // import "go.uber.org/multierr"
+
+import (
+ "bytes"
+ "errors"
+ "fmt"
+ "io"
+ "strings"
+ "sync"
+ "sync/atomic"
+)
+
+var (
+ // Separator for single-line error messages.
+ _singlelineSeparator = []byte("; ")
+
+ // Prefix for multi-line messages
+ _multilinePrefix = []byte("the following errors occurred:")
+
+ // Prefix for the first and following lines of an item in a list of
+ // multi-line error messages.
+ //
+ // For example, if a single item is:
+ //
+ // foo
+ // bar
+ //
+ // It will become,
+ //
+ // - foo
+ // bar
+ _multilineSeparator = []byte("\n - ")
+ _multilineIndent = []byte(" ")
+)
+
+// _bufferPool is a pool of bytes.Buffers.
+var _bufferPool = sync.Pool{
+ New: func() interface{} {
+ return &bytes.Buffer{}
+ },
+}
+
+type errorGroup interface {
+ Errors() []error
+}
+
+// Errors returns a slice containing zero or more errors that the supplied
+// error is composed of. If the error is nil, a nil slice is returned.
+//
+// err := multierr.Append(r.Close(), w.Close())
+// errors := multierr.Errors(err)
+//
+// If the error is not composed of other errors, the returned slice contains
+// just the error that was passed in.
+//
+// Callers of this function are free to modify the returned slice.
+func Errors(err error) []error {
+ return extractErrors(err)
+}
+
+// multiError is an error that holds one or more errors.
+//
+// An instance of this is guaranteed to be non-empty and flattened. That is,
+// none of the errors inside multiError are other multiErrors.
+//
+// multiError formats to a semi-colon delimited list of error messages with
+// %v and with a more readable multi-line format with %+v.
+type multiError struct {
+ copyNeeded atomic.Bool
+ errors []error
+}
+
+// Errors returns the list of underlying errors.
+//
+// This slice MUST NOT be modified.
+func (merr *multiError) Errors() []error {
+ if merr == nil {
+ return nil
+ }
+ return merr.errors
+}
+
+func (merr *multiError) Error() string {
+ if merr == nil {
+ return ""
+ }
+
+ buff := _bufferPool.Get().(*bytes.Buffer)
+ buff.Reset()
+
+ merr.writeSingleline(buff)
+
+ result := buff.String()
+ _bufferPool.Put(buff)
+ return result
+}
+
+// Every compares every error in the given err against the given target error
+// using [errors.Is], and returns true only if every comparison returned true.
+func Every(err error, target error) bool {
+ for _, e := range extractErrors(err) {
+ if !errors.Is(e, target) {
+ return false
+ }
+ }
+ return true
+}
+
+func (merr *multiError) Format(f fmt.State, c rune) {
+ if c == 'v' && f.Flag('+') {
+ merr.writeMultiline(f)
+ } else {
+ merr.writeSingleline(f)
+ }
+}
+
+func (merr *multiError) writeSingleline(w io.Writer) {
+ first := true
+ for _, item := range merr.errors {
+ if first {
+ first = false
+ } else {
+ w.Write(_singlelineSeparator)
+ }
+ io.WriteString(w, item.Error())
+ }
+}
+
+func (merr *multiError) writeMultiline(w io.Writer) {
+ w.Write(_multilinePrefix)
+ for _, item := range merr.errors {
+ w.Write(_multilineSeparator)
+ writePrefixLine(w, _multilineIndent, fmt.Sprintf("%+v", item))
+ }
+}
+
+// Writes s to the writer with the given prefix added before each line after
+// the first.
+func writePrefixLine(w io.Writer, prefix []byte, s string) {
+ first := true
+ for len(s) > 0 {
+ if first {
+ first = false
+ } else {
+ w.Write(prefix)
+ }
+
+ idx := strings.IndexByte(s, '\n')
+ if idx < 0 {
+ idx = len(s) - 1
+ }
+
+ io.WriteString(w, s[:idx+1])
+ s = s[idx+1:]
+ }
+}
+
+type inspectResult struct {
+ // Number of top-level non-nil errors
+ Count int
+
+ // Total number of errors including multiErrors
+ Capacity int
+
+ // Index of the first non-nil error in the list. Value is meaningless if
+ // Count is zero.
+ FirstErrorIdx int
+
+ // Whether the list contains at least one multiError
+ ContainsMultiError bool
+}
+
+// Inspects the given slice of errors so that we can efficiently allocate
+// space for it.
+func inspect(errors []error) (res inspectResult) {
+ first := true
+ for i, err := range errors {
+ if err == nil {
+ continue
+ }
+
+ res.Count++
+ if first {
+ first = false
+ res.FirstErrorIdx = i
+ }
+
+ if merr, ok := err.(*multiError); ok {
+ res.Capacity += len(merr.errors)
+ res.ContainsMultiError = true
+ } else {
+ res.Capacity++
+ }
+ }
+ return
+}
+
+// fromSlice converts the given list of errors into a single error.
+func fromSlice(errors []error) error {
+ // Don't pay to inspect small slices.
+ switch len(errors) {
+ case 0:
+ return nil
+ case 1:
+ return errors[0]
+ }
+
+ res := inspect(errors)
+ switch res.Count {
+ case 0:
+ return nil
+ case 1:
+ // only one non-nil entry
+ return errors[res.FirstErrorIdx]
+ case len(errors):
+ if !res.ContainsMultiError {
+ // Error list is flat. Make a copy of it
+ // Otherwise "errors" escapes to the heap
+ // unconditionally for all other cases.
+ // This lets us optimize for the "no errors" case.
+ out := append(([]error)(nil), errors...)
+ return &multiError{errors: out}
+ }
+ }
+
+ nonNilErrs := make([]error, 0, res.Capacity)
+ for _, err := range errors[res.FirstErrorIdx:] {
+ if err == nil {
+ continue
+ }
+
+ if nested, ok := err.(*multiError); ok {
+ nonNilErrs = append(nonNilErrs, nested.errors...)
+ } else {
+ nonNilErrs = append(nonNilErrs, err)
+ }
+ }
+
+ return &multiError{errors: nonNilErrs}
+}
+
+// Combine combines the passed errors into a single error.
+//
+// If zero arguments were passed or if all items are nil, a nil error is
+// returned.
+//
+// Combine(nil, nil) // == nil
+//
+// If only a single error was passed, it is returned as-is.
+//
+// Combine(err) // == err
+//
+// Combine skips over nil arguments so this function may be used to combine
+// together errors from operations that fail independently of each other.
+//
+// multierr.Combine(
+// reader.Close(),
+// writer.Close(),
+// pipe.Close(),
+// )
+//
+// If any of the passed errors is a multierr error, it will be flattened along
+// with the other errors.
+//
+// multierr.Combine(multierr.Combine(err1, err2), err3)
+// // is the same as
+// multierr.Combine(err1, err2, err3)
+//
+// The returned error formats into a readable multi-line error message if
+// formatted with %+v.
+//
+// fmt.Sprintf("%+v", multierr.Combine(err1, err2))
+func Combine(errors ...error) error {
+ return fromSlice(errors)
+}
+
+// Append appends the given errors together. Either value may be nil.
+//
+// This function is a specialization of Combine for the common case where
+// there are only two errors.
+//
+// err = multierr.Append(reader.Close(), writer.Close())
+//
+// The following pattern may also be used to record failure of deferred
+// operations without losing information about the original error.
+//
+// func doSomething(..) (err error) {
+// f := acquireResource()
+// defer func() {
+// err = multierr.Append(err, f.Close())
+// }()
+//
+// Note that the variable MUST be a named return to append an error to it from
+// the defer statement. See also [AppendInvoke].
+func Append(left error, right error) error {
+ switch {
+ case left == nil:
+ return right
+ case right == nil:
+ return left
+ }
+
+ if _, ok := right.(*multiError); !ok {
+ if l, ok := left.(*multiError); ok && !l.copyNeeded.Swap(true) {
+ // Common case where the error on the left is constantly being
+ // appended to.
+ errs := append(l.errors, right)
+ return &multiError{errors: errs}
+ } else if !ok {
+ // Both errors are single errors.
+ return &multiError{errors: []error{left, right}}
+ }
+ }
+
+ // Either right or both, left and right, are multiErrors. Rely on usual
+ // expensive logic.
+ errors := [2]error{left, right}
+ return fromSlice(errors[0:])
+}
+
+// AppendInto appends an error into the destination of an error pointer and
+// returns whether the error being appended was non-nil.
+//
+// var err error
+// multierr.AppendInto(&err, r.Close())
+// multierr.AppendInto(&err, w.Close())
+//
+// The above is equivalent to,
+//
+// err := multierr.Append(r.Close(), w.Close())
+//
+// As AppendInto reports whether the provided error was non-nil, it may be
+// used to build a multierr error in a loop more ergonomically. For example:
+//
+// var err error
+// for line := range lines {
+// var item Item
+// if multierr.AppendInto(&err, parse(line, &item)) {
+// continue
+// }
+// items = append(items, item)
+// }
+//
+// Compare this with a version that relies solely on Append:
+//
+// var err error
+// for line := range lines {
+// var item Item
+// if parseErr := parse(line, &item); parseErr != nil {
+// err = multierr.Append(err, parseErr)
+// continue
+// }
+// items = append(items, item)
+// }
+func AppendInto(into *error, err error) (errored bool) {
+ if into == nil {
+ // We panic if 'into' is nil. This is not documented above
+ // because suggesting that the pointer must be non-nil may
+ // confuse users into thinking that the error that it points
+ // to must be non-nil.
+ panic("misuse of multierr.AppendInto: into pointer must not be nil")
+ }
+
+ if err == nil {
+ return false
+ }
+ *into = Append(*into, err)
+ return true
+}
+
+// Invoker is an operation that may fail with an error. Use it with
+// AppendInvoke to append the result of calling the function into an error.
+// This allows you to conveniently defer capture of failing operations.
+//
+// See also, [Close] and [Invoke].
+type Invoker interface {
+ Invoke() error
+}
+
+// Invoke wraps a function which may fail with an error to match the Invoker
+// interface. Use it to supply functions matching this signature to
+// AppendInvoke.
+//
+// For example,
+//
+// func processReader(r io.Reader) (err error) {
+// scanner := bufio.NewScanner(r)
+// defer multierr.AppendInvoke(&err, multierr.Invoke(scanner.Err))
+// for scanner.Scan() {
+// // ...
+// }
+// // ...
+// }
+//
+// In this example, the following line will construct the Invoker right away,
+// but defer the invocation of scanner.Err() until the function returns.
+//
+// defer multierr.AppendInvoke(&err, multierr.Invoke(scanner.Err))
+//
+// Note that the error you're appending to from the defer statement MUST be a
+// named return.
+type Invoke func() error
+
+// Invoke calls the supplied function and returns its result.
+func (i Invoke) Invoke() error { return i() }
+
+// Close builds an Invoker that closes the provided io.Closer. Use it with
+// AppendInvoke to close io.Closers and append their results into an error.
+//
+// For example,
+//
+// func processFile(path string) (err error) {
+// f, err := os.Open(path)
+// if err != nil {
+// return err
+// }
+// defer multierr.AppendInvoke(&err, multierr.Close(f))
+// return processReader(f)
+// }
+//
+// In this example, multierr.Close will construct the Invoker right away, but
+// defer the invocation of f.Close until the function returns.
+//
+// defer multierr.AppendInvoke(&err, multierr.Close(f))
+//
+// Note that the error you're appending to from the defer statement MUST be a
+// named return.
+func Close(closer io.Closer) Invoker {
+ return Invoke(closer.Close)
+}
+
+// AppendInvoke appends the result of calling the given Invoker into the
+// provided error pointer. Use it with named returns to safely defer
+// invocation of fallible operations until a function returns, and capture the
+// resulting errors.
+//
+// func doSomething(...) (err error) {
+// // ...
+// f, err := openFile(..)
+// if err != nil {
+// return err
+// }
+//
+// // multierr will call f.Close() when this function returns and
+// // if the operation fails, its append its error into the
+// // returned error.
+// defer multierr.AppendInvoke(&err, multierr.Close(f))
+//
+// scanner := bufio.NewScanner(f)
+// // Similarly, this scheduled scanner.Err to be called and
+// // inspected when the function returns and append its error
+// // into the returned error.
+// defer multierr.AppendInvoke(&err, multierr.Invoke(scanner.Err))
+//
+// // ...
+// }
+//
+// NOTE: If used with a defer, the error variable MUST be a named return.
+//
+// Without defer, AppendInvoke behaves exactly like AppendInto.
+//
+// err := // ...
+// multierr.AppendInvoke(&err, mutltierr.Invoke(foo))
+//
+// // ...is roughly equivalent to...
+//
+// err := // ...
+// multierr.AppendInto(&err, foo())
+//
+// The advantage of the indirection introduced by Invoker is to make it easy
+// to defer the invocation of a function. Without this indirection, the
+// invoked function will be evaluated at the time of the defer block rather
+// than when the function returns.
+//
+// // BAD: This is likely not what the caller intended. This will evaluate
+// // foo() right away and append its result into the error when the
+// // function returns.
+// defer multierr.AppendInto(&err, foo())
+//
+// // GOOD: This will defer invocation of foo unutil the function returns.
+// defer multierr.AppendInvoke(&err, multierr.Invoke(foo))
+//
+// multierr provides a few Invoker implementations out of the box for
+// convenience. See [Invoker] for more information.
+func AppendInvoke(into *error, invoker Invoker) {
+ AppendInto(into, invoker.Invoke())
+}
+
+// AppendFunc is a shorthand for [AppendInvoke].
+// It allows using function or method value directly
+// without having to wrap it into an [Invoker] interface.
+//
+// func doSomething(...) (err error) {
+// w, err := startWorker(...)
+// if err != nil {
+// return err
+// }
+//
+// // multierr will call w.Stop() when this function returns and
+// // if the operation fails, it appends its error into the
+// // returned error.
+// defer multierr.AppendFunc(&err, w.Stop)
+// }
+func AppendFunc(into *error, fn func() error) {
+ AppendInvoke(into, Invoke(fn))
+}
diff --git a/vendor/go.uber.org/multierr/error_post_go120.go b/vendor/go.uber.org/multierr/error_post_go120.go
new file mode 100644
index 000000000..a173f9c25
--- /dev/null
+++ b/vendor/go.uber.org/multierr/error_post_go120.go
@@ -0,0 +1,48 @@
+// Copyright (c) 2017-2023 Uber Technologies, Inc.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+//go:build go1.20
+// +build go1.20
+
+package multierr
+
+// Unwrap returns a list of errors wrapped by this multierr.
+func (merr *multiError) Unwrap() []error {
+ return merr.Errors()
+}
+
+type multipleErrors interface {
+ Unwrap() []error
+}
+
+func extractErrors(err error) []error {
+ if err == nil {
+ return nil
+ }
+
+ // check if the given err is an Unwrapable error that
+ // implements multipleErrors interface.
+ eg, ok := err.(multipleErrors)
+ if !ok {
+ return []error{err}
+ }
+
+ return append(([]error)(nil), eg.Unwrap()...)
+}
diff --git a/vendor/go.uber.org/multierr/error_pre_go120.go b/vendor/go.uber.org/multierr/error_pre_go120.go
new file mode 100644
index 000000000..93872a3fc
--- /dev/null
+++ b/vendor/go.uber.org/multierr/error_pre_go120.go
@@ -0,0 +1,79 @@
+// Copyright (c) 2017-2023 Uber Technologies, Inc.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+//go:build !go1.20
+// +build !go1.20
+
+package multierr
+
+import "errors"
+
+// Versions of Go before 1.20 did not support the Unwrap() []error method.
+// This provides a similar behavior by implementing the Is(..) and As(..)
+// methods.
+// See the errors.Join proposal for details:
+// https://github.com/golang/go/issues/53435
+
+// As attempts to find the first error in the error list that matches the type
+// of the value that target points to.
+//
+// This function allows errors.As to traverse the values stored on the
+// multierr error.
+func (merr *multiError) As(target interface{}) bool {
+ for _, err := range merr.Errors() {
+ if errors.As(err, target) {
+ return true
+ }
+ }
+ return false
+}
+
+// Is attempts to match the provided error against errors in the error list.
+//
+// This function allows errors.Is to traverse the values stored on the
+// multierr error.
+func (merr *multiError) Is(target error) bool {
+ for _, err := range merr.Errors() {
+ if errors.Is(err, target) {
+ return true
+ }
+ }
+ return false
+}
+
+func extractErrors(err error) []error {
+ if err == nil {
+ return nil
+ }
+
+ // Note that we're casting to multiError, not errorGroup. Our contract is
+ // that returned errors MAY implement errorGroup. Errors, however, only
+ // has special behavior for multierr-specific error objects.
+ //
+ // This behavior can be expanded in the future but I think it's prudent to
+ // start with as little as possible in terms of contract and possibility
+ // of misuse.
+ eg, ok := err.(*multiError)
+ if !ok {
+ return []error{err}
+ }
+
+ return append(([]error)(nil), eg.Errors()...)
+}
diff --git a/vendor/golang.org/x/exp/slices/cmp.go b/vendor/golang.org/x/exp/slices/cmp.go
new file mode 100644
index 000000000..fbf1934a0
--- /dev/null
+++ b/vendor/golang.org/x/exp/slices/cmp.go
@@ -0,0 +1,44 @@
+// Copyright 2023 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.
+
+package slices
+
+import "golang.org/x/exp/constraints"
+
+// min is a version of the predeclared function from the Go 1.21 release.
+func min[T constraints.Ordered](a, b T) T {
+ if a < b || isNaN(a) {
+ return a
+ }
+ return b
+}
+
+// max is a version of the predeclared function from the Go 1.21 release.
+func max[T constraints.Ordered](a, b T) T {
+ if a > b || isNaN(a) {
+ return a
+ }
+ return b
+}
+
+// cmpLess is a copy of cmp.Less from the Go 1.21 release.
+func cmpLess[T constraints.Ordered](x, y T) bool {
+ return (isNaN(x) && !isNaN(y)) || x < y
+}
+
+// cmpCompare is a copy of cmp.Compare from the Go 1.21 release.
+func cmpCompare[T constraints.Ordered](x, y T) int {
+ xNaN := isNaN(x)
+ yNaN := isNaN(y)
+ if xNaN && yNaN {
+ return 0
+ }
+ if xNaN || x < y {
+ return -1
+ }
+ if yNaN || x > y {
+ return +1
+ }
+ return 0
+}
diff --git a/vendor/golang.org/x/exp/slices/slices.go b/vendor/golang.org/x/exp/slices/slices.go
index 2540bd682..5e8158bba 100644
--- a/vendor/golang.org/x/exp/slices/slices.go
+++ b/vendor/golang.org/x/exp/slices/slices.go
@@ -3,23 +3,20 @@
// license that can be found in the LICENSE file.
// Package slices defines various functions useful with slices of any type.
-// Unless otherwise specified, these functions all apply to the elements
-// of a slice at index 0 <= i < len(s).
-//
-// Note that the less function in IsSortedFunc, SortFunc, SortStableFunc requires a
-// strict weak ordering (https://en.wikipedia.org/wiki/Weak_ordering#Strict_weak_orderings),
-// or the sorting may fail to sort correctly. A common case is when sorting slices of
-// floating-point numbers containing NaN values.
package slices
-import "golang.org/x/exp/constraints"
+import (
+ "unsafe"
+
+ "golang.org/x/exp/constraints"
+)
// Equal reports whether two slices are equal: the same length and all
// elements equal. If the lengths are different, Equal returns false.
// Otherwise, the elements are compared in increasing index order, and the
// comparison stops at the first unequal pair.
// Floating point NaNs are not considered equal.
-func Equal[E comparable](s1, s2 []E) bool {
+func Equal[S ~[]E, E comparable](s1, s2 S) bool {
if len(s1) != len(s2) {
return false
}
@@ -31,12 +28,12 @@ func Equal[E comparable](s1, s2 []E) bool {
return true
}
-// EqualFunc reports whether two slices are equal using a comparison
+// EqualFunc reports whether two slices are equal using an equality
// function on each pair of elements. If the lengths are different,
// EqualFunc returns false. Otherwise, the elements are compared in
// increasing index order, and the comparison stops at the first index
// for which eq returns false.
-func EqualFunc[E1, E2 any](s1 []E1, s2 []E2, eq func(E1, E2) bool) bool {
+func EqualFunc[S1 ~[]E1, S2 ~[]E2, E1, E2 any](s1 S1, s2 S2, eq func(E1, E2) bool) bool {
if len(s1) != len(s2) {
return false
}
@@ -49,45 +46,37 @@ func EqualFunc[E1, E2 any](s1 []E1, s2 []E2, eq func(E1, E2) bool) bool {
return true
}
-// Compare compares the elements of s1 and s2.
-// The elements are compared sequentially, starting at index 0,
+// Compare compares the elements of s1 and s2, using [cmp.Compare] on each pair
+// of elements. The elements are compared sequentially, starting at index 0,
// until one element is not equal to the other.
// The result of comparing the first non-matching elements is returned.
// If both slices are equal until one of them ends, the shorter slice is
// considered less than the longer one.
// The result is 0 if s1 == s2, -1 if s1 < s2, and +1 if s1 > s2.
-// Comparisons involving floating point NaNs are ignored.
-func Compare[E constraints.Ordered](s1, s2 []E) int {
- s2len := len(s2)
+func Compare[S ~[]E, E constraints.Ordered](s1, s2 S) int {
for i, v1 := range s1 {
- if i >= s2len {
+ if i >= len(s2) {
return +1
}
v2 := s2[i]
- switch {
- case v1 < v2:
- return -1
- case v1 > v2:
- return +1
+ if c := cmpCompare(v1, v2); c != 0 {
+ return c
}
}
- if len(s1) < s2len {
+ if len(s1) < len(s2) {
return -1
}
return 0
}
-// CompareFunc is like Compare but uses a comparison function
-// on each pair of elements. The elements are compared in increasing
-// index order, and the comparisons stop after the first time cmp
-// returns non-zero.
+// CompareFunc is like [Compare] but uses a custom comparison function on each
+// pair of elements.
// The result is the first non-zero result of cmp; if cmp always
// returns 0 the result is 0 if len(s1) == len(s2), -1 if len(s1) < len(s2),
// and +1 if len(s1) > len(s2).
-func CompareFunc[E1, E2 any](s1 []E1, s2 []E2, cmp func(E1, E2) int) int {
- s2len := len(s2)
+func CompareFunc[S1 ~[]E1, S2 ~[]E2, E1, E2 any](s1 S1, s2 S2, cmp func(E1, E2) int) int {
for i, v1 := range s1 {
- if i >= s2len {
+ if i >= len(s2) {
return +1
}
v2 := s2[i]
@@ -95,7 +84,7 @@ func CompareFunc[E1, E2 any](s1 []E1, s2 []E2, cmp func(E1, E2) int) int {
return c
}
}
- if len(s1) < s2len {
+ if len(s1) < len(s2) {
return -1
}
return 0
@@ -103,7 +92,7 @@ func CompareFunc[E1, E2 any](s1 []E1, s2 []E2, cmp func(E1, E2) int) int {
// Index returns the index of the first occurrence of v in s,
// or -1 if not present.
-func Index[E comparable](s []E, v E) int {
+func Index[S ~[]E, E comparable](s S, v E) int {
for i := range s {
if v == s[i] {
return i
@@ -114,7 +103,7 @@ func Index[E comparable](s []E, v E) int {
// IndexFunc returns the first index i satisfying f(s[i]),
// or -1 if none do.
-func IndexFunc[E any](s []E, f func(E) bool) int {
+func IndexFunc[S ~[]E, E any](s S, f func(E) bool) int {
for i := range s {
if f(s[i]) {
return i
@@ -124,39 +113,104 @@ func IndexFunc[E any](s []E, f func(E) bool) int {
}
// Contains reports whether v is present in s.
-func Contains[E comparable](s []E, v E) bool {
+func Contains[S ~[]E, E comparable](s S, v E) bool {
return Index(s, v) >= 0
}
// ContainsFunc reports whether at least one
// element e of s satisfies f(e).
-func ContainsFunc[E any](s []E, f func(E) bool) bool {
+func ContainsFunc[S ~[]E, E any](s S, f func(E) bool) bool {
return IndexFunc(s, f) >= 0
}
// Insert inserts the values v... into s at index i,
// returning the modified slice.
-// In the returned slice r, r[i] == v[0].
+// The elements at s[i:] are shifted up to make room.
+// In the returned slice r, r[i] == v[0],
+// and r[i+len(v)] == value originally at r[i].
// Insert panics if i is out of range.
// This function is O(len(s) + len(v)).
func Insert[S ~[]E, E any](s S, i int, v ...E) S {
- tot := len(s) + len(v)
- if tot <= cap(s) {
- s2 := s[:tot]
- copy(s2[i+len(v):], s[i:])
+ m := len(v)
+ if m == 0 {
+ return s
+ }
+ n := len(s)
+ if i == n {
+ return append(s, v...)
+ }
+ if n+m > cap(s) {
+ // Use append rather than make so that we bump the size of
+ // the slice up to the next storage class.
+ // This is what Grow does but we don't call Grow because
+ // that might copy the values twice.
+ s2 := append(s[:i], make(S, n+m-i)...)
copy(s2[i:], v)
+ copy(s2[i+m:], s[i:])
return s2
}
- s2 := make(S, tot)
- copy(s2, s[:i])
- copy(s2[i:], v)
- copy(s2[i+len(v):], s[i:])
- return s2
+ s = s[:n+m]
+
+ // before:
+ // s: aaaaaaaabbbbccccccccdddd
+ // ^ ^ ^ ^
+ // i i+m n n+m
+ // after:
+ // s: aaaaaaaavvvvbbbbcccccccc
+ // ^ ^ ^ ^
+ // i i+m n n+m
+ //
+ // a are the values that don't move in s.
+ // v are the values copied in from v.
+ // b and c are the values from s that are shifted up in index.
+ // d are the values that get overwritten, never to be seen again.
+
+ if !overlaps(v, s[i+m:]) {
+ // Easy case - v does not overlap either the c or d regions.
+ // (It might be in some of a or b, or elsewhere entirely.)
+ // The data we copy up doesn't write to v at all, so just do it.
+
+ copy(s[i+m:], s[i:])
+
+ // Now we have
+ // s: aaaaaaaabbbbbbbbcccccccc
+ // ^ ^ ^ ^
+ // i i+m n n+m
+ // Note the b values are duplicated.
+
+ copy(s[i:], v)
+
+ // Now we have
+ // s: aaaaaaaavvvvbbbbcccccccc
+ // ^ ^ ^ ^
+ // i i+m n n+m
+ // That's the result we want.
+ return s
+ }
+
+ // The hard case - v overlaps c or d. We can't just shift up
+ // the data because we'd move or clobber the values we're trying
+ // to insert.
+ // So instead, write v on top of d, then rotate.
+ copy(s[n:], v)
+
+ // Now we have
+ // s: aaaaaaaabbbbccccccccvvvv
+ // ^ ^ ^ ^
+ // i i+m n n+m
+
+ rotateRight(s[i:], m)
+
+ // Now we have
+ // s: aaaaaaaavvvvbbbbcccccccc
+ // ^ ^ ^ ^
+ // i i+m n n+m
+ // That's the result we want.
+ return s
}
// Delete removes the elements s[i:j] from s, returning the modified slice.
// Delete panics if s[i:j] is not a valid slice of s.
-// Delete modifies the contents of the slice s; it does not create a new slice.
// Delete is O(len(s)-j), so if many items must be deleted, it is better to
// make a single call deleting them all together than to delete one at a time.
// Delete might not modify the elements s[len(s)-(j-i):len(s)]. If those
@@ -168,22 +222,113 @@ func Delete[S ~[]E, E any](s S, i, j int) S {
return append(s[:i], s[j:]...)
}
+// DeleteFunc removes any elements from s for which del returns true,
+// returning the modified slice.
+// When DeleteFunc removes m elements, it might not modify the elements
+// s[len(s)-m:len(s)]. If those elements contain pointers you might consider
+// zeroing those elements so that objects they reference can be garbage
+// collected.
+func DeleteFunc[S ~[]E, E any](s S, del func(E) bool) S {
+ i := IndexFunc(s, del)
+ if i == -1 {
+ return s
+ }
+ // Don't start copying elements until we find one to delete.
+ for j := i + 1; j < len(s); j++ {
+ if v := s[j]; !del(v) {
+ s[i] = v
+ i++
+ }
+ }
+ return s[:i]
+}
+
// Replace replaces the elements s[i:j] by the given v, and returns the
// modified slice. Replace panics if s[i:j] is not a valid slice of s.
func Replace[S ~[]E, E any](s S, i, j int, v ...E) S {
_ = s[i:j] // verify that i:j is a valid subslice
+
+ if i == j {
+ return Insert(s, i, v...)
+ }
+ if j == len(s) {
+ return append(s[:i], v...)
+ }
+
tot := len(s[:i]) + len(v) + len(s[j:])
- if tot <= cap(s) {
- s2 := s[:tot]
- copy(s2[i+len(v):], s[j:])
+ if tot > cap(s) {
+ // Too big to fit, allocate and copy over.
+ s2 := append(s[:i], make(S, tot-i)...) // See Insert
copy(s2[i:], v)
+ copy(s2[i+len(v):], s[j:])
return s2
}
- s2 := make(S, tot)
- copy(s2, s[:i])
- copy(s2[i:], v)
- copy(s2[i+len(v):], s[j:])
- return s2
+
+ r := s[:tot]
+
+ if i+len(v) <= j {
+ // Easy, as v fits in the deleted portion.
+ copy(r[i:], v)
+ if i+len(v) != j {
+ copy(r[i+len(v):], s[j:])
+ }
+ return r
+ }
+
+ // We are expanding (v is bigger than j-i).
+ // The situation is something like this:
+ // (example has i=4,j=8,len(s)=16,len(v)=6)
+ // s: aaaaxxxxbbbbbbbbyy
+ // ^ ^ ^ ^
+ // i j len(s) tot
+ // a: prefix of s
+ // x: deleted range
+ // b: more of s
+ // y: area to expand into
+
+ if !overlaps(r[i+len(v):], v) {
+ // Easy, as v is not clobbered by the first copy.
+ copy(r[i+len(v):], s[j:])
+ copy(r[i:], v)
+ return r
+ }
+
+ // This is a situation where we don't have a single place to which
+ // we can copy v. Parts of it need to go to two different places.
+ // We want to copy the prefix of v into y and the suffix into x, then
+ // rotate |y| spots to the right.
+ //
+ // v[2:] v[:2]
+ // | |
+ // s: aaaavvvvbbbbbbbbvv
+ // ^ ^ ^ ^
+ // i j len(s) tot
+ //
+ // If either of those two destinations don't alias v, then we're good.
+ y := len(v) - (j - i) // length of y portion
+
+ if !overlaps(r[i:j], v) {
+ copy(r[i:j], v[y:])
+ copy(r[len(s):], v[:y])
+ rotateRight(r[i:], y)
+ return r
+ }
+ if !overlaps(r[len(s):], v) {
+ copy(r[len(s):], v[:y])
+ copy(r[i:j], v[y:])
+ rotateRight(r[i:], y)
+ return r
+ }
+
+ // Now we know that v overlaps both x and y.
+ // That means that the entirety of b is *inside* v.
+ // So we don't need to preserve b at all; instead we
+ // can copy v first, then copy the b part of v out of
+ // v to the right destination.
+ k := startIdx(v, s[j:])
+ copy(r[i:], v)
+ copy(r[i+len(v):], r[i+k:])
+ return r
}
// Clone returns a copy of the slice.
@@ -198,7 +343,8 @@ func Clone[S ~[]E, E any](s S) S {
// Compact replaces consecutive runs of equal elements with a single copy.
// This is like the uniq command found on Unix.
-// Compact modifies the contents of the slice s; it does not create a new slice.
+// Compact modifies the contents of the slice s and returns the modified slice,
+// which may have a smaller length.
// When Compact discards m elements in total, it might not modify the elements
// s[len(s)-m:len(s)]. If those elements contain pointers you might consider
// zeroing those elements so that objects they reference can be garbage collected.
@@ -218,7 +364,8 @@ func Compact[S ~[]E, E comparable](s S) S {
return s[:i]
}
-// CompactFunc is like Compact but uses a comparison function.
+// CompactFunc is like [Compact] but uses an equality function to compare elements.
+// For runs of elements that compare equal, CompactFunc keeps the first one.
func CompactFunc[S ~[]E, E any](s S, eq func(E, E) bool) S {
if len(s) < 2 {
return s
@@ -256,3 +403,97 @@ func Grow[S ~[]E, E any](s S, n int) S {
func Clip[S ~[]E, E any](s S) S {
return s[:len(s):len(s)]
}
+
+// Rotation algorithm explanation:
+//
+// rotate left by 2
+// start with
+// 0123456789
+// split up like this
+// 01 234567 89
+// swap first 2 and last 2
+// 89 234567 01
+// join first parts
+// 89234567 01
+// recursively rotate first left part by 2
+// 23456789 01
+// join at the end
+// 2345678901
+//
+// rotate left by 8
+// start with
+// 0123456789
+// split up like this
+// 01 234567 89
+// swap first 2 and last 2
+// 89 234567 01
+// join last parts
+// 89 23456701
+// recursively rotate second part left by 6
+// 89 01234567
+// join at the end
+// 8901234567
+
+// TODO: There are other rotate algorithms.
+// This algorithm has the desirable property that it moves each element exactly twice.
+// The triple-reverse algorithm is simpler and more cache friendly, but takes more writes.
+// The follow-cycles algorithm can be 1-write but it is not very cache friendly.
+
+// rotateLeft rotates b left by n spaces.
+// s_final[i] = s_orig[i+r], wrapping around.
+func rotateLeft[E any](s []E, r int) {
+ for r != 0 && r != len(s) {
+ if r*2 <= len(s) {
+ swap(s[:r], s[len(s)-r:])
+ s = s[:len(s)-r]
+ } else {
+ swap(s[:len(s)-r], s[r:])
+ s, r = s[len(s)-r:], r*2-len(s)
+ }
+ }
+}
+func rotateRight[E any](s []E, r int) {
+ rotateLeft(s, len(s)-r)
+}
+
+// swap swaps the contents of x and y. x and y must be equal length and disjoint.
+func swap[E any](x, y []E) {
+ for i := 0; i < len(x); i++ {
+ x[i], y[i] = y[i], x[i]
+ }
+}
+
+// overlaps reports whether the memory ranges a[0:len(a)] and b[0:len(b)] overlap.
+func overlaps[E any](a, b []E) bool {
+ if len(a) == 0 || len(b) == 0 {
+ return false
+ }
+ elemSize := unsafe.Sizeof(a[0])
+ if elemSize == 0 {
+ return false
+ }
+ // TODO: use a runtime/unsafe facility once one becomes available. See issue 12445.
+ // Also see crypto/internal/alias/alias.go:AnyOverlap
+ return uintptr(unsafe.Pointer(&a[0])) <= uintptr(unsafe.Pointer(&b[len(b)-1]))+(elemSize-1) &&
+ uintptr(unsafe.Pointer(&b[0])) <= uintptr(unsafe.Pointer(&a[len(a)-1]))+(elemSize-1)
+}
+
+// startIdx returns the index in haystack where the needle starts.
+// prerequisite: the needle must be aliased entirely inside the haystack.
+func startIdx[E any](haystack, needle []E) int {
+ p := &needle[0]
+ for i := range haystack {
+ if p == &haystack[i] {
+ return i
+ }
+ }
+ // TODO: what if the overlap is by a non-integral number of Es?
+ panic("needle not found")
+}
+
+// Reverse reverses the elements of the slice in place.
+func Reverse[S ~[]E, E any](s S) {
+ for i, j := 0, len(s)-1; i < j; i, j = i+1, j-1 {
+ s[i], s[j] = s[j], s[i]
+ }
+}
diff --git a/vendor/golang.org/x/exp/slices/sort.go b/vendor/golang.org/x/exp/slices/sort.go
index 231b6448a..b67897f76 100644
--- a/vendor/golang.org/x/exp/slices/sort.go
+++ b/vendor/golang.org/x/exp/slices/sort.go
@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+//go:generate go run $GOROOT/src/sort/gen_sort_variants.go -exp
+
package slices
import (
@@ -11,57 +13,116 @@ import (
)
// Sort sorts a slice of any ordered type in ascending order.
-// Sort may fail to sort correctly when sorting slices of floating-point
-// numbers containing Not-a-number (NaN) values.
-// Use slices.SortFunc(x, func(a, b float64) bool {return a < b || (math.IsNaN(a) && !math.IsNaN(b))})
-// instead if the input may contain NaNs.
-func Sort[E constraints.Ordered](x []E) {
+// When sorting floating-point numbers, NaNs are ordered before other values.
+func Sort[S ~[]E, E constraints.Ordered](x S) {
n := len(x)
pdqsortOrdered(x, 0, n, bits.Len(uint(n)))
}
-// SortFunc sorts the slice x in ascending order as determined by the less function.
-// This sort is not guaranteed to be stable.
+// SortFunc sorts the slice x in ascending order as determined by the cmp
+// function. This sort is not guaranteed to be stable.
+// cmp(a, b) should return a negative number when a < b, a positive number when
+// a > b and zero when a == b.
//
-// SortFunc requires that less is a strict weak ordering.
+// SortFunc requires that cmp is a strict weak ordering.
// See https://en.wikipedia.org/wiki/Weak_ordering#Strict_weak_orderings.
-func SortFunc[E any](x []E, less func(a, b E) bool) {
+func SortFunc[S ~[]E, E any](x S, cmp func(a, b E) int) {
n := len(x)
- pdqsortLessFunc(x, 0, n, bits.Len(uint(n)), less)
+ pdqsortCmpFunc(x, 0, n, bits.Len(uint(n)), cmp)
}
// SortStableFunc sorts the slice x while keeping the original order of equal
-// elements, using less to compare elements.
-func SortStableFunc[E any](x []E, less func(a, b E) bool) {
- stableLessFunc(x, len(x), less)
+// elements, using cmp to compare elements in the same way as [SortFunc].
+func SortStableFunc[S ~[]E, E any](x S, cmp func(a, b E) int) {
+ stableCmpFunc(x, len(x), cmp)
}
// IsSorted reports whether x is sorted in ascending order.
-func IsSorted[E constraints.Ordered](x []E) bool {
+func IsSorted[S ~[]E, E constraints.Ordered](x S) bool {
for i := len(x) - 1; i > 0; i-- {
- if x[i] < x[i-1] {
+ if cmpLess(x[i], x[i-1]) {
return false
}
}
return true
}
-// IsSortedFunc reports whether x is sorted in ascending order, with less as the
-// comparison function.
-func IsSortedFunc[E any](x []E, less func(a, b E) bool) bool {
+// IsSortedFunc reports whether x is sorted in ascending order, with cmp as the
+// comparison function as defined by [SortFunc].
+func IsSortedFunc[S ~[]E, E any](x S, cmp func(a, b E) int) bool {
for i := len(x) - 1; i > 0; i-- {
- if less(x[i], x[i-1]) {
+ if cmp(x[i], x[i-1]) < 0 {
return false
}
}
return true
}
+// Min returns the minimal value in x. It panics if x is empty.
+// For floating-point numbers, Min propagates NaNs (any NaN value in x
+// forces the output to be NaN).
+func Min[S ~[]E, E constraints.Ordered](x S) E {
+ if len(x) < 1 {
+ panic("slices.Min: empty list")
+ }
+ m := x[0]
+ for i := 1; i < len(x); i++ {
+ m = min(m, x[i])
+ }
+ return m
+}
+
+// MinFunc returns the minimal value in x, using cmp to compare elements.
+// It panics if x is empty. If there is more than one minimal element
+// according to the cmp function, MinFunc returns the first one.
+func MinFunc[S ~[]E, E any](x S, cmp func(a, b E) int) E {
+ if len(x) < 1 {
+ panic("slices.MinFunc: empty list")
+ }
+ m := x[0]
+ for i := 1; i < len(x); i++ {
+ if cmp(x[i], m) < 0 {
+ m = x[i]
+ }
+ }
+ return m
+}
+
+// Max returns the maximal value in x. It panics if x is empty.
+// For floating-point E, Max propagates NaNs (any NaN value in x
+// forces the output to be NaN).
+func Max[S ~[]E, E constraints.Ordered](x S) E {
+ if len(x) < 1 {
+ panic("slices.Max: empty list")
+ }
+ m := x[0]
+ for i := 1; i < len(x); i++ {
+ m = max(m, x[i])
+ }
+ return m
+}
+
+// MaxFunc returns the maximal value in x, using cmp to compare elements.
+// It panics if x is empty. If there is more than one maximal element
+// according to the cmp function, MaxFunc returns the first one.
+func MaxFunc[S ~[]E, E any](x S, cmp func(a, b E) int) E {
+ if len(x) < 1 {
+ panic("slices.MaxFunc: empty list")
+ }
+ m := x[0]
+ for i := 1; i < len(x); i++ {
+ if cmp(x[i], m) > 0 {
+ m = x[i]
+ }
+ }
+ return m
+}
+
// BinarySearch searches for target in a sorted slice and returns the position
// where target is found, or the position where target would appear in the
// sort order; it also returns a bool saying whether the target is really found
// in the slice. The slice must be sorted in increasing order.
-func BinarySearch[E constraints.Ordered](x []E, target E) (int, bool) {
+func BinarySearch[S ~[]E, E constraints.Ordered](x S, target E) (int, bool) {
// Inlining is faster than calling BinarySearchFunc with a lambda.
n := len(x)
// Define x[-1] < target and x[n] >= target.
@@ -70,24 +131,24 @@ func BinarySearch[E constraints.Ordered](x []E, target E) (int, bool) {
for i < j {
h := int(uint(i+j) >> 1) // avoid overflow when computing h
// i ≤ h < j
- if x[h] < target {
+ if cmpLess(x[h], target) {
i = h + 1 // preserves x[i-1] < target
} else {
j = h // preserves x[j] >= target
}
}
// i == j, x[i-1] < target, and x[j] (= x[i]) >= target => answer is i.
- return i, i < n && x[i] == target
+ return i, i < n && (x[i] == target || (isNaN(x[i]) && isNaN(target)))
}
-// BinarySearchFunc works like BinarySearch, but uses a custom comparison
+// BinarySearchFunc works like [BinarySearch], but uses a custom comparison
// function. The slice must be sorted in increasing order, where "increasing"
// is defined by cmp. cmp should return 0 if the slice element matches
// the target, a negative number if the slice element precedes the target,
// or a positive number if the slice element follows the target.
// cmp must implement the same ordering as the slice, such that if
// cmp(a, t) < 0 and cmp(b, t) >= 0, then a must precede b in the slice.
-func BinarySearchFunc[E, T any](x []E, target T, cmp func(E, T) int) (int, bool) {
+func BinarySearchFunc[S ~[]E, E, T any](x S, target T, cmp func(E, T) int) (int, bool) {
n := len(x)
// Define cmp(x[-1], target) < 0 and cmp(x[n], target) >= 0 .
// Invariant: cmp(x[i - 1], target) < 0, cmp(x[j], target) >= 0.
@@ -126,3 +187,9 @@ func (r *xorshift) Next() uint64 {
func nextPowerOfTwo(length int) uint {
return 1 << bits.Len(uint(length))
}
+
+// isNaN reports whether x is a NaN without requiring the math package.
+// This will always return false if T is not floating-point.
+func isNaN[T constraints.Ordered](x T) bool {
+ return x != x
+}
diff --git a/vendor/golang.org/x/exp/slices/zsortfunc.go b/vendor/golang.org/x/exp/slices/zsortanyfunc.go
similarity index 64%
rename from vendor/golang.org/x/exp/slices/zsortfunc.go
rename to vendor/golang.org/x/exp/slices/zsortanyfunc.go
index 2a632476c..06f2c7a24 100644
--- a/vendor/golang.org/x/exp/slices/zsortfunc.go
+++ b/vendor/golang.org/x/exp/slices/zsortanyfunc.go
@@ -6,28 +6,28 @@
package slices
-// insertionSortLessFunc sorts data[a:b] using insertion sort.
-func insertionSortLessFunc[E any](data []E, a, b int, less func(a, b E) bool) {
+// insertionSortCmpFunc sorts data[a:b] using insertion sort.
+func insertionSortCmpFunc[E any](data []E, a, b int, cmp func(a, b E) int) {
for i := a + 1; i < b; i++ {
- for j := i; j > a && less(data[j], data[j-1]); j-- {
+ for j := i; j > a && (cmp(data[j], data[j-1]) < 0); j-- {
data[j], data[j-1] = data[j-1], data[j]
}
}
}
-// siftDownLessFunc implements the heap property on data[lo:hi].
+// siftDownCmpFunc implements the heap property on data[lo:hi].
// first is an offset into the array where the root of the heap lies.
-func siftDownLessFunc[E any](data []E, lo, hi, first int, less func(a, b E) bool) {
+func siftDownCmpFunc[E any](data []E, lo, hi, first int, cmp func(a, b E) int) {
root := lo
for {
child := 2*root + 1
if child >= hi {
break
}
- if child+1 < hi && less(data[first+child], data[first+child+1]) {
+ if child+1 < hi && (cmp(data[first+child], data[first+child+1]) < 0) {
child++
}
- if !less(data[first+root], data[first+child]) {
+ if !(cmp(data[first+root], data[first+child]) < 0) {
return
}
data[first+root], data[first+child] = data[first+child], data[first+root]
@@ -35,30 +35,30 @@ func siftDownLessFunc[E any](data []E, lo, hi, first int, less func(a, b E) bool
}
}
-func heapSortLessFunc[E any](data []E, a, b int, less func(a, b E) bool) {
+func heapSortCmpFunc[E any](data []E, a, b int, cmp func(a, b E) int) {
first := a
lo := 0
hi := b - a
// Build heap with greatest element at top.
for i := (hi - 1) / 2; i >= 0; i-- {
- siftDownLessFunc(data, i, hi, first, less)
+ siftDownCmpFunc(data, i, hi, first, cmp)
}
// Pop elements, largest first, into end of data.
for i := hi - 1; i >= 0; i-- {
data[first], data[first+i] = data[first+i], data[first]
- siftDownLessFunc(data, lo, i, first, less)
+ siftDownCmpFunc(data, lo, i, first, cmp)
}
}
-// pdqsortLessFunc sorts data[a:b].
+// pdqsortCmpFunc sorts data[a:b].
// The algorithm based on pattern-defeating quicksort(pdqsort), but without the optimizations from BlockQuicksort.
// pdqsort paper: https://arxiv.org/pdf/2106.05123.pdf
// C++ implementation: https://github.com/orlp/pdqsort
// Rust implementation: https://docs.rs/pdqsort/latest/pdqsort/
// limit is the number of allowed bad (very unbalanced) pivots before falling back to heapsort.
-func pdqsortLessFunc[E any](data []E, a, b, limit int, less func(a, b E) bool) {
+func pdqsortCmpFunc[E any](data []E, a, b, limit int, cmp func(a, b E) int) {
const maxInsertion = 12
var (
@@ -70,25 +70,25 @@ func pdqsortLessFunc[E any](data []E, a, b, limit int, less func(a, b E) bool) {
length := b - a
if length <= maxInsertion {
- insertionSortLessFunc(data, a, b, less)
+ insertionSortCmpFunc(data, a, b, cmp)
return
}
// Fall back to heapsort if too many bad choices were made.
if limit == 0 {
- heapSortLessFunc(data, a, b, less)
+ heapSortCmpFunc(data, a, b, cmp)
return
}
// If the last partitioning was imbalanced, we need to breaking patterns.
if !wasBalanced {
- breakPatternsLessFunc(data, a, b, less)
+ breakPatternsCmpFunc(data, a, b, cmp)
limit--
}
- pivot, hint := choosePivotLessFunc(data, a, b, less)
+ pivot, hint := choosePivotCmpFunc(data, a, b, cmp)
if hint == decreasingHint {
- reverseRangeLessFunc(data, a, b, less)
+ reverseRangeCmpFunc(data, a, b, cmp)
// The chosen pivot was pivot-a elements after the start of the array.
// After reversing it is pivot-a elements before the end of the array.
// The idea came from Rust's implementation.
@@ -98,48 +98,48 @@ func pdqsortLessFunc[E any](data []E, a, b, limit int, less func(a, b E) bool) {
// The slice is likely already sorted.
if wasBalanced && wasPartitioned && hint == increasingHint {
- if partialInsertionSortLessFunc(data, a, b, less) {
+ if partialInsertionSortCmpFunc(data, a, b, cmp) {
return
}
}
// Probably the slice contains many duplicate elements, partition the slice into
// elements equal to and elements greater than the pivot.
- if a > 0 && !less(data[a-1], data[pivot]) {
- mid := partitionEqualLessFunc(data, a, b, pivot, less)
+ if a > 0 && !(cmp(data[a-1], data[pivot]) < 0) {
+ mid := partitionEqualCmpFunc(data, a, b, pivot, cmp)
a = mid
continue
}
- mid, alreadyPartitioned := partitionLessFunc(data, a, b, pivot, less)
+ mid, alreadyPartitioned := partitionCmpFunc(data, a, b, pivot, cmp)
wasPartitioned = alreadyPartitioned
leftLen, rightLen := mid-a, b-mid
balanceThreshold := length / 8
if leftLen < rightLen {
wasBalanced = leftLen >= balanceThreshold
- pdqsortLessFunc(data, a, mid, limit, less)
+ pdqsortCmpFunc(data, a, mid, limit, cmp)
a = mid + 1
} else {
wasBalanced = rightLen >= balanceThreshold
- pdqsortLessFunc(data, mid+1, b, limit, less)
+ pdqsortCmpFunc(data, mid+1, b, limit, cmp)
b = mid
}
}
}
-// partitionLessFunc does one quicksort partition.
+// partitionCmpFunc does one quicksort partition.
// Let p = data[pivot]
// Moves elements in data[a:b] around, so that data[i]=p for inewpivot.
// On return, data[newpivot] = p
-func partitionLessFunc[E any](data []E, a, b, pivot int, less func(a, b E) bool) (newpivot int, alreadyPartitioned bool) {
+func partitionCmpFunc[E any](data []E, a, b, pivot int, cmp func(a, b E) int) (newpivot int, alreadyPartitioned bool) {
data[a], data[pivot] = data[pivot], data[a]
i, j := a+1, b-1 // i and j are inclusive of the elements remaining to be partitioned
- for i <= j && less(data[i], data[a]) {
+ for i <= j && (cmp(data[i], data[a]) < 0) {
i++
}
- for i <= j && !less(data[j], data[a]) {
+ for i <= j && !(cmp(data[j], data[a]) < 0) {
j--
}
if i > j {
@@ -151,10 +151,10 @@ func partitionLessFunc[E any](data []E, a, b, pivot int, less func(a, b E) bool)
j--
for {
- for i <= j && less(data[i], data[a]) {
+ for i <= j && (cmp(data[i], data[a]) < 0) {
i++
}
- for i <= j && !less(data[j], data[a]) {
+ for i <= j && !(cmp(data[j], data[a]) < 0) {
j--
}
if i > j {
@@ -168,17 +168,17 @@ func partitionLessFunc[E any](data []E, a, b, pivot int, less func(a, b E) bool)
return j, false
}
-// partitionEqualLessFunc partitions data[a:b] into elements equal to data[pivot] followed by elements greater than data[pivot].
+// partitionEqualCmpFunc partitions data[a:b] into elements equal to data[pivot] followed by elements greater than data[pivot].
// It assumed that data[a:b] does not contain elements smaller than the data[pivot].
-func partitionEqualLessFunc[E any](data []E, a, b, pivot int, less func(a, b E) bool) (newpivot int) {
+func partitionEqualCmpFunc[E any](data []E, a, b, pivot int, cmp func(a, b E) int) (newpivot int) {
data[a], data[pivot] = data[pivot], data[a]
i, j := a+1, b-1 // i and j are inclusive of the elements remaining to be partitioned
for {
- for i <= j && !less(data[a], data[i]) {
+ for i <= j && !(cmp(data[a], data[i]) < 0) {
i++
}
- for i <= j && less(data[a], data[j]) {
+ for i <= j && (cmp(data[a], data[j]) < 0) {
j--
}
if i > j {
@@ -191,15 +191,15 @@ func partitionEqualLessFunc[E any](data []E, a, b, pivot int, less func(a, b E)
return i
}
-// partialInsertionSortLessFunc partially sorts a slice, returns true if the slice is sorted at the end.
-func partialInsertionSortLessFunc[E any](data []E, a, b int, less func(a, b E) bool) bool {
+// partialInsertionSortCmpFunc partially sorts a slice, returns true if the slice is sorted at the end.
+func partialInsertionSortCmpFunc[E any](data []E, a, b int, cmp func(a, b E) int) bool {
const (
maxSteps = 5 // maximum number of adjacent out-of-order pairs that will get shifted
shortestShifting = 50 // don't shift any elements on short arrays
)
i := a + 1
for j := 0; j < maxSteps; j++ {
- for i < b && !less(data[i], data[i-1]) {
+ for i < b && !(cmp(data[i], data[i-1]) < 0) {
i++
}
@@ -216,7 +216,7 @@ func partialInsertionSortLessFunc[E any](data []E, a, b int, less func(a, b E) b
// Shift the smaller one to the left.
if i-a >= 2 {
for j := i - 1; j >= 1; j-- {
- if !less(data[j], data[j-1]) {
+ if !(cmp(data[j], data[j-1]) < 0) {
break
}
data[j], data[j-1] = data[j-1], data[j]
@@ -225,7 +225,7 @@ func partialInsertionSortLessFunc[E any](data []E, a, b int, less func(a, b E) b
// Shift the greater one to the right.
if b-i >= 2 {
for j := i + 1; j < b; j++ {
- if !less(data[j], data[j-1]) {
+ if !(cmp(data[j], data[j-1]) < 0) {
break
}
data[j], data[j-1] = data[j-1], data[j]
@@ -235,9 +235,9 @@ func partialInsertionSortLessFunc[E any](data []E, a, b int, less func(a, b E) b
return false
}
-// breakPatternsLessFunc scatters some elements around in an attempt to break some patterns
+// breakPatternsCmpFunc scatters some elements around in an attempt to break some patterns
// that might cause imbalanced partitions in quicksort.
-func breakPatternsLessFunc[E any](data []E, a, b int, less func(a, b E) bool) {
+func breakPatternsCmpFunc[E any](data []E, a, b int, cmp func(a, b E) int) {
length := b - a
if length >= 8 {
random := xorshift(length)
@@ -253,12 +253,12 @@ func breakPatternsLessFunc[E any](data []E, a, b int, less func(a, b E) bool) {
}
}
-// choosePivotLessFunc chooses a pivot in data[a:b].
+// choosePivotCmpFunc chooses a pivot in data[a:b].
//
// [0,8): chooses a static pivot.
// [8,shortestNinther): uses the simple median-of-three method.
// [shortestNinther,∞): uses the Tukey ninther method.
-func choosePivotLessFunc[E any](data []E, a, b int, less func(a, b E) bool) (pivot int, hint sortedHint) {
+func choosePivotCmpFunc[E any](data []E, a, b int, cmp func(a, b E) int) (pivot int, hint sortedHint) {
const (
shortestNinther = 50
maxSwaps = 4 * 3
@@ -276,12 +276,12 @@ func choosePivotLessFunc[E any](data []E, a, b int, less func(a, b E) bool) (piv
if l >= 8 {
if l >= shortestNinther {
// Tukey ninther method, the idea came from Rust's implementation.
- i = medianAdjacentLessFunc(data, i, &swaps, less)
- j = medianAdjacentLessFunc(data, j, &swaps, less)
- k = medianAdjacentLessFunc(data, k, &swaps, less)
+ i = medianAdjacentCmpFunc(data, i, &swaps, cmp)
+ j = medianAdjacentCmpFunc(data, j, &swaps, cmp)
+ k = medianAdjacentCmpFunc(data, k, &swaps, cmp)
}
// Find the median among i, j, k and stores it into j.
- j = medianLessFunc(data, i, j, k, &swaps, less)
+ j = medianCmpFunc(data, i, j, k, &swaps, cmp)
}
switch swaps {
@@ -294,29 +294,29 @@ func choosePivotLessFunc[E any](data []E, a, b int, less func(a, b E) bool) (piv
}
}
-// order2LessFunc returns x,y where data[x] <= data[y], where x,y=a,b or x,y=b,a.
-func order2LessFunc[E any](data []E, a, b int, swaps *int, less func(a, b E) bool) (int, int) {
- if less(data[b], data[a]) {
+// order2CmpFunc returns x,y where data[x] <= data[y], where x,y=a,b or x,y=b,a.
+func order2CmpFunc[E any](data []E, a, b int, swaps *int, cmp func(a, b E) int) (int, int) {
+ if cmp(data[b], data[a]) < 0 {
*swaps++
return b, a
}
return a, b
}
-// medianLessFunc returns x where data[x] is the median of data[a],data[b],data[c], where x is a, b, or c.
-func medianLessFunc[E any](data []E, a, b, c int, swaps *int, less func(a, b E) bool) int {
- a, b = order2LessFunc(data, a, b, swaps, less)
- b, c = order2LessFunc(data, b, c, swaps, less)
- a, b = order2LessFunc(data, a, b, swaps, less)
+// medianCmpFunc returns x where data[x] is the median of data[a],data[b],data[c], where x is a, b, or c.
+func medianCmpFunc[E any](data []E, a, b, c int, swaps *int, cmp func(a, b E) int) int {
+ a, b = order2CmpFunc(data, a, b, swaps, cmp)
+ b, c = order2CmpFunc(data, b, c, swaps, cmp)
+ a, b = order2CmpFunc(data, a, b, swaps, cmp)
return b
}
-// medianAdjacentLessFunc finds the median of data[a - 1], data[a], data[a + 1] and stores the index into a.
-func medianAdjacentLessFunc[E any](data []E, a int, swaps *int, less func(a, b E) bool) int {
- return medianLessFunc(data, a-1, a, a+1, swaps, less)
+// medianAdjacentCmpFunc finds the median of data[a - 1], data[a], data[a + 1] and stores the index into a.
+func medianAdjacentCmpFunc[E any](data []E, a int, swaps *int, cmp func(a, b E) int) int {
+ return medianCmpFunc(data, a-1, a, a+1, swaps, cmp)
}
-func reverseRangeLessFunc[E any](data []E, a, b int, less func(a, b E) bool) {
+func reverseRangeCmpFunc[E any](data []E, a, b int, cmp func(a, b E) int) {
i := a
j := b - 1
for i < j {
@@ -326,37 +326,37 @@ func reverseRangeLessFunc[E any](data []E, a, b int, less func(a, b E) bool) {
}
}
-func swapRangeLessFunc[E any](data []E, a, b, n int, less func(a, b E) bool) {
+func swapRangeCmpFunc[E any](data []E, a, b, n int, cmp func(a, b E) int) {
for i := 0; i < n; i++ {
data[a+i], data[b+i] = data[b+i], data[a+i]
}
}
-func stableLessFunc[E any](data []E, n int, less func(a, b E) bool) {
+func stableCmpFunc[E any](data []E, n int, cmp func(a, b E) int) {
blockSize := 20 // must be > 0
a, b := 0, blockSize
for b <= n {
- insertionSortLessFunc(data, a, b, less)
+ insertionSortCmpFunc(data, a, b, cmp)
a = b
b += blockSize
}
- insertionSortLessFunc(data, a, n, less)
+ insertionSortCmpFunc(data, a, n, cmp)
for blockSize < n {
a, b = 0, 2*blockSize
for b <= n {
- symMergeLessFunc(data, a, a+blockSize, b, less)
+ symMergeCmpFunc(data, a, a+blockSize, b, cmp)
a = b
b += 2 * blockSize
}
if m := a + blockSize; m < n {
- symMergeLessFunc(data, a, m, n, less)
+ symMergeCmpFunc(data, a, m, n, cmp)
}
blockSize *= 2
}
}
-// symMergeLessFunc merges the two sorted subsequences data[a:m] and data[m:b] using
+// symMergeCmpFunc merges the two sorted subsequences data[a:m] and data[m:b] using
// the SymMerge algorithm from Pok-Son Kim and Arne Kutzner, "Stable Minimum
// Storage Merging by Symmetric Comparisons", in Susanne Albers and Tomasz
// Radzik, editors, Algorithms - ESA 2004, volume 3221 of Lecture Notes in
@@ -375,7 +375,7 @@ func stableLessFunc[E any](data []E, n int, less func(a, b E) bool) {
// symMerge assumes non-degenerate arguments: a < m && m < b.
// Having the caller check this condition eliminates many leaf recursion calls,
// which improves performance.
-func symMergeLessFunc[E any](data []E, a, m, b int, less func(a, b E) bool) {
+func symMergeCmpFunc[E any](data []E, a, m, b int, cmp func(a, b E) int) {
// Avoid unnecessary recursions of symMerge
// by direct insertion of data[a] into data[m:b]
// if data[a:m] only contains one element.
@@ -387,7 +387,7 @@ func symMergeLessFunc[E any](data []E, a, m, b int, less func(a, b E) bool) {
j := b
for i < j {
h := int(uint(i+j) >> 1)
- if less(data[h], data[a]) {
+ if cmp(data[h], data[a]) < 0 {
i = h + 1
} else {
j = h
@@ -411,7 +411,7 @@ func symMergeLessFunc[E any](data []E, a, m, b int, less func(a, b E) bool) {
j := m
for i < j {
h := int(uint(i+j) >> 1)
- if !less(data[m], data[h]) {
+ if !(cmp(data[m], data[h]) < 0) {
i = h + 1
} else {
j = h
@@ -438,7 +438,7 @@ func symMergeLessFunc[E any](data []E, a, m, b int, less func(a, b E) bool) {
for start < r {
c := int(uint(start+r) >> 1)
- if !less(data[p-c], data[c]) {
+ if !(cmp(data[p-c], data[c]) < 0) {
start = c + 1
} else {
r = c
@@ -447,33 +447,33 @@ func symMergeLessFunc[E any](data []E, a, m, b int, less func(a, b E) bool) {
end := n - start
if start < m && m < end {
- rotateLessFunc(data, start, m, end, less)
+ rotateCmpFunc(data, start, m, end, cmp)
}
if a < start && start < mid {
- symMergeLessFunc(data, a, start, mid, less)
+ symMergeCmpFunc(data, a, start, mid, cmp)
}
if mid < end && end < b {
- symMergeLessFunc(data, mid, end, b, less)
+ symMergeCmpFunc(data, mid, end, b, cmp)
}
}
-// rotateLessFunc rotates two consecutive blocks u = data[a:m] and v = data[m:b] in data:
+// rotateCmpFunc rotates two consecutive blocks u = data[a:m] and v = data[m:b] in data:
// Data of the form 'x u v y' is changed to 'x v u y'.
// rotate performs at most b-a many calls to data.Swap,
// and it assumes non-degenerate arguments: a < m && m < b.
-func rotateLessFunc[E any](data []E, a, m, b int, less func(a, b E) bool) {
+func rotateCmpFunc[E any](data []E, a, m, b int, cmp func(a, b E) int) {
i := m - a
j := b - m
for i != j {
if i > j {
- swapRangeLessFunc(data, m-i, m, j, less)
+ swapRangeCmpFunc(data, m-i, m, j, cmp)
i -= j
} else {
- swapRangeLessFunc(data, m-i, m+j-i, i, less)
+ swapRangeCmpFunc(data, m-i, m+j-i, i, cmp)
j -= i
}
}
// i == j
- swapRangeLessFunc(data, m-i, m, i, less)
+ swapRangeCmpFunc(data, m-i, m, i, cmp)
}
diff --git a/vendor/golang.org/x/exp/slices/zsortordered.go b/vendor/golang.org/x/exp/slices/zsortordered.go
index efaa1c8b7..99b47c398 100644
--- a/vendor/golang.org/x/exp/slices/zsortordered.go
+++ b/vendor/golang.org/x/exp/slices/zsortordered.go
@@ -11,7 +11,7 @@ import "golang.org/x/exp/constraints"
// insertionSortOrdered sorts data[a:b] using insertion sort.
func insertionSortOrdered[E constraints.Ordered](data []E, a, b int) {
for i := a + 1; i < b; i++ {
- for j := i; j > a && (data[j] < data[j-1]); j-- {
+ for j := i; j > a && cmpLess(data[j], data[j-1]); j-- {
data[j], data[j-1] = data[j-1], data[j]
}
}
@@ -26,10 +26,10 @@ func siftDownOrdered[E constraints.Ordered](data []E, lo, hi, first int) {
if child >= hi {
break
}
- if child+1 < hi && (data[first+child] < data[first+child+1]) {
+ if child+1 < hi && cmpLess(data[first+child], data[first+child+1]) {
child++
}
- if !(data[first+root] < data[first+child]) {
+ if !cmpLess(data[first+root], data[first+child]) {
return
}
data[first+root], data[first+child] = data[first+child], data[first+root]
@@ -107,7 +107,7 @@ func pdqsortOrdered[E constraints.Ordered](data []E, a, b, limit int) {
// Probably the slice contains many duplicate elements, partition the slice into
// elements equal to and elements greater than the pivot.
- if a > 0 && !(data[a-1] < data[pivot]) {
+ if a > 0 && !cmpLess(data[a-1], data[pivot]) {
mid := partitionEqualOrdered(data, a, b, pivot)
a = mid
continue
@@ -138,10 +138,10 @@ func partitionOrdered[E constraints.Ordered](data []E, a, b, pivot int) (newpivo
data[a], data[pivot] = data[pivot], data[a]
i, j := a+1, b-1 // i and j are inclusive of the elements remaining to be partitioned
- for i <= j && (data[i] < data[a]) {
+ for i <= j && cmpLess(data[i], data[a]) {
i++
}
- for i <= j && !(data[j] < data[a]) {
+ for i <= j && !cmpLess(data[j], data[a]) {
j--
}
if i > j {
@@ -153,10 +153,10 @@ func partitionOrdered[E constraints.Ordered](data []E, a, b, pivot int) (newpivo
j--
for {
- for i <= j && (data[i] < data[a]) {
+ for i <= j && cmpLess(data[i], data[a]) {
i++
}
- for i <= j && !(data[j] < data[a]) {
+ for i <= j && !cmpLess(data[j], data[a]) {
j--
}
if i > j {
@@ -177,10 +177,10 @@ func partitionEqualOrdered[E constraints.Ordered](data []E, a, b, pivot int) (ne
i, j := a+1, b-1 // i and j are inclusive of the elements remaining to be partitioned
for {
- for i <= j && !(data[a] < data[i]) {
+ for i <= j && !cmpLess(data[a], data[i]) {
i++
}
- for i <= j && (data[a] < data[j]) {
+ for i <= j && cmpLess(data[a], data[j]) {
j--
}
if i > j {
@@ -201,7 +201,7 @@ func partialInsertionSortOrdered[E constraints.Ordered](data []E, a, b int) bool
)
i := a + 1
for j := 0; j < maxSteps; j++ {
- for i < b && !(data[i] < data[i-1]) {
+ for i < b && !cmpLess(data[i], data[i-1]) {
i++
}
@@ -218,7 +218,7 @@ func partialInsertionSortOrdered[E constraints.Ordered](data []E, a, b int) bool
// Shift the smaller one to the left.
if i-a >= 2 {
for j := i - 1; j >= 1; j-- {
- if !(data[j] < data[j-1]) {
+ if !cmpLess(data[j], data[j-1]) {
break
}
data[j], data[j-1] = data[j-1], data[j]
@@ -227,7 +227,7 @@ func partialInsertionSortOrdered[E constraints.Ordered](data []E, a, b int) bool
// Shift the greater one to the right.
if b-i >= 2 {
for j := i + 1; j < b; j++ {
- if !(data[j] < data[j-1]) {
+ if !cmpLess(data[j], data[j-1]) {
break
}
data[j], data[j-1] = data[j-1], data[j]
@@ -298,7 +298,7 @@ func choosePivotOrdered[E constraints.Ordered](data []E, a, b int) (pivot int, h
// order2Ordered returns x,y where data[x] <= data[y], where x,y=a,b or x,y=b,a.
func order2Ordered[E constraints.Ordered](data []E, a, b int, swaps *int) (int, int) {
- if data[b] < data[a] {
+ if cmpLess(data[b], data[a]) {
*swaps++
return b, a
}
@@ -389,7 +389,7 @@ func symMergeOrdered[E constraints.Ordered](data []E, a, m, b int) {
j := b
for i < j {
h := int(uint(i+j) >> 1)
- if data[h] < data[a] {
+ if cmpLess(data[h], data[a]) {
i = h + 1
} else {
j = h
@@ -413,7 +413,7 @@ func symMergeOrdered[E constraints.Ordered](data []E, a, m, b int) {
j := m
for i < j {
h := int(uint(i+j) >> 1)
- if !(data[m] < data[h]) {
+ if !cmpLess(data[m], data[h]) {
i = h + 1
} else {
j = h
@@ -440,7 +440,7 @@ func symMergeOrdered[E constraints.Ordered](data []E, a, m, b int) {
for start < r {
c := int(uint(start+r) >> 1)
- if !(data[p-c] < data[c]) {
+ if !cmpLess(data[p-c], data[c]) {
start = c + 1
} else {
r = c
diff --git a/vendor/golang.org/x/exp/slog/attr.go b/vendor/golang.org/x/exp/slog/attr.go
new file mode 100644
index 000000000..a180d0e1d
--- /dev/null
+++ b/vendor/golang.org/x/exp/slog/attr.go
@@ -0,0 +1,102 @@
+// Copyright 2022 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.
+
+package slog
+
+import (
+ "fmt"
+ "time"
+)
+
+// An Attr is a key-value pair.
+type Attr struct {
+ Key string
+ Value Value
+}
+
+// String returns an Attr for a string value.
+func String(key, value string) Attr {
+ return Attr{key, StringValue(value)}
+}
+
+// Int64 returns an Attr for an int64.
+func Int64(key string, value int64) Attr {
+ return Attr{key, Int64Value(value)}
+}
+
+// Int converts an int to an int64 and returns
+// an Attr with that value.
+func Int(key string, value int) Attr {
+ return Int64(key, int64(value))
+}
+
+// Uint64 returns an Attr for a uint64.
+func Uint64(key string, v uint64) Attr {
+ return Attr{key, Uint64Value(v)}
+}
+
+// Float64 returns an Attr for a floating-point number.
+func Float64(key string, v float64) Attr {
+ return Attr{key, Float64Value(v)}
+}
+
+// Bool returns an Attr for a bool.
+func Bool(key string, v bool) Attr {
+ return Attr{key, BoolValue(v)}
+}
+
+// Time returns an Attr for a time.Time.
+// It discards the monotonic portion.
+func Time(key string, v time.Time) Attr {
+ return Attr{key, TimeValue(v)}
+}
+
+// Duration returns an Attr for a time.Duration.
+func Duration(key string, v time.Duration) Attr {
+ return Attr{key, DurationValue(v)}
+}
+
+// Group returns an Attr for a Group Value.
+// The first argument is the key; the remaining arguments
+// are converted to Attrs as in [Logger.Log].
+//
+// Use Group to collect several key-value pairs under a single
+// key on a log line, or as the result of LogValue
+// in order to log a single value as multiple Attrs.
+func Group(key string, args ...any) Attr {
+ return Attr{key, GroupValue(argsToAttrSlice(args)...)}
+}
+
+func argsToAttrSlice(args []any) []Attr {
+ var (
+ attr Attr
+ attrs []Attr
+ )
+ for len(args) > 0 {
+ attr, args = argsToAttr(args)
+ attrs = append(attrs, attr)
+ }
+ return attrs
+}
+
+// Any returns an Attr for the supplied value.
+// See [Value.AnyValue] for how values are treated.
+func Any(key string, value any) Attr {
+ return Attr{key, AnyValue(value)}
+}
+
+// Equal reports whether a and b have equal keys and values.
+func (a Attr) Equal(b Attr) bool {
+ return a.Key == b.Key && a.Value.Equal(b.Value)
+}
+
+func (a Attr) String() string {
+ return fmt.Sprintf("%s=%s", a.Key, a.Value)
+}
+
+// isEmpty reports whether a has an empty key and a nil value.
+// That can be written as Attr{} or Any("", nil).
+func (a Attr) isEmpty() bool {
+ return a.Key == "" && a.Value.num == 0 && a.Value.any == nil
+}
diff --git a/vendor/golang.org/x/exp/slog/doc.go b/vendor/golang.org/x/exp/slog/doc.go
new file mode 100644
index 000000000..4beaf8674
--- /dev/null
+++ b/vendor/golang.org/x/exp/slog/doc.go
@@ -0,0 +1,316 @@
+// Copyright 2022 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.
+
+/*
+Package slog provides structured logging,
+in which log records include a message,
+a severity level, and various other attributes
+expressed as key-value pairs.
+
+It defines a type, [Logger],
+which provides several methods (such as [Logger.Info] and [Logger.Error])
+for reporting events of interest.
+
+Each Logger is associated with a [Handler].
+A Logger output method creates a [Record] from the method arguments
+and passes it to the Handler, which decides how to handle it.
+There is a default Logger accessible through top-level functions
+(such as [Info] and [Error]) that call the corresponding Logger methods.
+
+A log record consists of a time, a level, a message, and a set of key-value
+pairs, where the keys are strings and the values may be of any type.
+As an example,
+
+ slog.Info("hello", "count", 3)
+
+creates a record containing the time of the call,
+a level of Info, the message "hello", and a single
+pair with key "count" and value 3.
+
+The [Info] top-level function calls the [Logger.Info] method on the default Logger.
+In addition to [Logger.Info], there are methods for Debug, Warn and Error levels.
+Besides these convenience methods for common levels,
+there is also a [Logger.Log] method which takes the level as an argument.
+Each of these methods has a corresponding top-level function that uses the
+default logger.
+
+The default handler formats the log record's message, time, level, and attributes
+as a string and passes it to the [log] package.
+
+ 2022/11/08 15:28:26 INFO hello count=3
+
+For more control over the output format, create a logger with a different handler.
+This statement uses [New] to create a new logger with a TextHandler
+that writes structured records in text form to standard error:
+
+ logger := slog.New(slog.NewTextHandler(os.Stderr, nil))
+
+[TextHandler] output is a sequence of key=value pairs, easily and unambiguously
+parsed by machine. This statement:
+
+ logger.Info("hello", "count", 3)
+
+produces this output:
+
+ time=2022-11-08T15:28:26.000-05:00 level=INFO msg=hello count=3
+
+The package also provides [JSONHandler], whose output is line-delimited JSON:
+
+ logger := slog.New(slog.NewJSONHandler(os.Stdout, nil))
+ logger.Info("hello", "count", 3)
+
+produces this output:
+
+ {"time":"2022-11-08T15:28:26.000000000-05:00","level":"INFO","msg":"hello","count":3}
+
+Both [TextHandler] and [JSONHandler] can be configured with [HandlerOptions].
+There are options for setting the minimum level (see Levels, below),
+displaying the source file and line of the log call, and
+modifying attributes before they are logged.
+
+Setting a logger as the default with
+
+ slog.SetDefault(logger)
+
+will cause the top-level functions like [Info] to use it.
+[SetDefault] also updates the default logger used by the [log] package,
+so that existing applications that use [log.Printf] and related functions
+will send log records to the logger's handler without needing to be rewritten.
+
+Some attributes are common to many log calls.
+For example, you may wish to include the URL or trace identifier of a server request
+with all log events arising from the request.
+Rather than repeat the attribute with every log call, you can use [Logger.With]
+to construct a new Logger containing the attributes:
+
+ logger2 := logger.With("url", r.URL)
+
+The arguments to With are the same key-value pairs used in [Logger.Info].
+The result is a new Logger with the same handler as the original, but additional
+attributes that will appear in the output of every call.
+
+# Levels
+
+A [Level] is an integer representing the importance or severity of a log event.
+The higher the level, the more severe the event.
+This package defines constants for the most common levels,
+but any int can be used as a level.
+
+In an application, you may wish to log messages only at a certain level or greater.
+One common configuration is to log messages at Info or higher levels,
+suppressing debug logging until it is needed.
+The built-in handlers can be configured with the minimum level to output by
+setting [HandlerOptions.Level].
+The program's `main` function typically does this.
+The default value is LevelInfo.
+
+Setting the [HandlerOptions.Level] field to a [Level] value
+fixes the handler's minimum level throughout its lifetime.
+Setting it to a [LevelVar] allows the level to be varied dynamically.
+A LevelVar holds a Level and is safe to read or write from multiple
+goroutines.
+To vary the level dynamically for an entire program, first initialize
+a global LevelVar:
+
+ var programLevel = new(slog.LevelVar) // Info by default
+
+Then use the LevelVar to construct a handler, and make it the default:
+
+ h := slog.NewJSONHandler(os.Stderr, &slog.HandlerOptions{Level: programLevel})
+ slog.SetDefault(slog.New(h))
+
+Now the program can change its logging level with a single statement:
+
+ programLevel.Set(slog.LevelDebug)
+
+# Groups
+
+Attributes can be collected into groups.
+A group has a name that is used to qualify the names of its attributes.
+How this qualification is displayed depends on the handler.
+[TextHandler] separates the group and attribute names with a dot.
+[JSONHandler] treats each group as a separate JSON object, with the group name as the key.
+
+Use [Group] to create a Group attribute from a name and a list of key-value pairs:
+
+ slog.Group("request",
+ "method", r.Method,
+ "url", r.URL)
+
+TextHandler would display this group as
+
+ request.method=GET request.url=http://example.com
+
+JSONHandler would display it as
+
+ "request":{"method":"GET","url":"http://example.com"}
+
+Use [Logger.WithGroup] to qualify all of a Logger's output
+with a group name. Calling WithGroup on a Logger results in a
+new Logger with the same Handler as the original, but with all
+its attributes qualified by the group name.
+
+This can help prevent duplicate attribute keys in large systems,
+where subsystems might use the same keys.
+Pass each subsystem a different Logger with its own group name so that
+potential duplicates are qualified:
+
+ logger := slog.Default().With("id", systemID)
+ parserLogger := logger.WithGroup("parser")
+ parseInput(input, parserLogger)
+
+When parseInput logs with parserLogger, its keys will be qualified with "parser",
+so even if it uses the common key "id", the log line will have distinct keys.
+
+# Contexts
+
+Some handlers may wish to include information from the [context.Context] that is
+available at the call site. One example of such information
+is the identifier for the current span when tracing is enabled.
+
+The [Logger.Log] and [Logger.LogAttrs] methods take a context as a first
+argument, as do their corresponding top-level functions.
+
+Although the convenience methods on Logger (Info and so on) and the
+corresponding top-level functions do not take a context, the alternatives ending
+in "Context" do. For example,
+
+ slog.InfoContext(ctx, "message")
+
+It is recommended to pass a context to an output method if one is available.
+
+# Attrs and Values
+
+An [Attr] is a key-value pair. The Logger output methods accept Attrs as well as
+alternating keys and values. The statement
+
+ slog.Info("hello", slog.Int("count", 3))
+
+behaves the same as
+
+ slog.Info("hello", "count", 3)
+
+There are convenience constructors for [Attr] such as [Int], [String], and [Bool]
+for common types, as well as the function [Any] for constructing Attrs of any
+type.
+
+The value part of an Attr is a type called [Value].
+Like an [any], a Value can hold any Go value,
+but it can represent typical values, including all numbers and strings,
+without an allocation.
+
+For the most efficient log output, use [Logger.LogAttrs].
+It is similar to [Logger.Log] but accepts only Attrs, not alternating
+keys and values; this allows it, too, to avoid allocation.
+
+The call
+
+ logger.LogAttrs(nil, slog.LevelInfo, "hello", slog.Int("count", 3))
+
+is the most efficient way to achieve the same output as
+
+ slog.Info("hello", "count", 3)
+
+# Customizing a type's logging behavior
+
+If a type implements the [LogValuer] interface, the [Value] returned from its LogValue
+method is used for logging. You can use this to control how values of the type
+appear in logs. For example, you can redact secret information like passwords,
+or gather a struct's fields in a Group. See the examples under [LogValuer] for
+details.
+
+A LogValue method may return a Value that itself implements [LogValuer]. The [Value.Resolve]
+method handles these cases carefully, avoiding infinite loops and unbounded recursion.
+Handler authors and others may wish to use Value.Resolve instead of calling LogValue directly.
+
+# Wrapping output methods
+
+The logger functions use reflection over the call stack to find the file name
+and line number of the logging call within the application. This can produce
+incorrect source information for functions that wrap slog. For instance, if you
+define this function in file mylog.go:
+
+ func Infof(format string, args ...any) {
+ slog.Default().Info(fmt.Sprintf(format, args...))
+ }
+
+and you call it like this in main.go:
+
+ Infof(slog.Default(), "hello, %s", "world")
+
+then slog will report the source file as mylog.go, not main.go.
+
+A correct implementation of Infof will obtain the source location
+(pc) and pass it to NewRecord.
+The Infof function in the package-level example called "wrapping"
+demonstrates how to do this.
+
+# Working with Records
+
+Sometimes a Handler will need to modify a Record
+before passing it on to another Handler or backend.
+A Record contains a mixture of simple public fields (e.g. Time, Level, Message)
+and hidden fields that refer to state (such as attributes) indirectly. This
+means that modifying a simple copy of a Record (e.g. by calling
+[Record.Add] or [Record.AddAttrs] to add attributes)
+may have unexpected effects on the original.
+Before modifying a Record, use [Clone] to
+create a copy that shares no state with the original,
+or create a new Record with [NewRecord]
+and build up its Attrs by traversing the old ones with [Record.Attrs].
+
+# Performance considerations
+
+If profiling your application demonstrates that logging is taking significant time,
+the following suggestions may help.
+
+If many log lines have a common attribute, use [Logger.With] to create a Logger with
+that attribute. The built-in handlers will format that attribute only once, at the
+call to [Logger.With]. The [Handler] interface is designed to allow that optimization,
+and a well-written Handler should take advantage of it.
+
+The arguments to a log call are always evaluated, even if the log event is discarded.
+If possible, defer computation so that it happens only if the value is actually logged.
+For example, consider the call
+
+ slog.Info("starting request", "url", r.URL.String()) // may compute String unnecessarily
+
+The URL.String method will be called even if the logger discards Info-level events.
+Instead, pass the URL directly:
+
+ slog.Info("starting request", "url", &r.URL) // calls URL.String only if needed
+
+The built-in [TextHandler] will call its String method, but only
+if the log event is enabled.
+Avoiding the call to String also preserves the structure of the underlying value.
+For example [JSONHandler] emits the components of the parsed URL as a JSON object.
+If you want to avoid eagerly paying the cost of the String call
+without causing the handler to potentially inspect the structure of the value,
+wrap the value in a fmt.Stringer implementation that hides its Marshal methods.
+
+You can also use the [LogValuer] interface to avoid unnecessary work in disabled log
+calls. Say you need to log some expensive value:
+
+ slog.Debug("frobbing", "value", computeExpensiveValue(arg))
+
+Even if this line is disabled, computeExpensiveValue will be called.
+To avoid that, define a type implementing LogValuer:
+
+ type expensive struct { arg int }
+
+ func (e expensive) LogValue() slog.Value {
+ return slog.AnyValue(computeExpensiveValue(e.arg))
+ }
+
+Then use a value of that type in log calls:
+
+ slog.Debug("frobbing", "value", expensive{arg})
+
+Now computeExpensiveValue will only be called when the line is enabled.
+
+The built-in handlers acquire a lock before calling [io.Writer.Write]
+to ensure that each record is written in one piece. User-defined
+handlers are responsible for their own locking.
+*/
+package slog
diff --git a/vendor/golang.org/x/exp/slog/handler.go b/vendor/golang.org/x/exp/slog/handler.go
new file mode 100644
index 000000000..bd635cb81
--- /dev/null
+++ b/vendor/golang.org/x/exp/slog/handler.go
@@ -0,0 +1,577 @@
+// Copyright 2022 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.
+
+package slog
+
+import (
+ "context"
+ "fmt"
+ "io"
+ "reflect"
+ "strconv"
+ "sync"
+ "time"
+
+ "golang.org/x/exp/slices"
+ "golang.org/x/exp/slog/internal/buffer"
+)
+
+// A Handler handles log records produced by a Logger..
+//
+// A typical handler may print log records to standard error,
+// or write them to a file or database, or perhaps augment them
+// with additional attributes and pass them on to another handler.
+//
+// Any of the Handler's methods may be called concurrently with itself
+// or with other methods. It is the responsibility of the Handler to
+// manage this concurrency.
+//
+// Users of the slog package should not invoke Handler methods directly.
+// They should use the methods of [Logger] instead.
+type Handler interface {
+ // Enabled reports whether the handler handles records at the given level.
+ // The handler ignores records whose level is lower.
+ // It is called early, before any arguments are processed,
+ // to save effort if the log event should be discarded.
+ // If called from a Logger method, the first argument is the context
+ // passed to that method, or context.Background() if nil was passed
+ // or the method does not take a context.
+ // The context is passed so Enabled can use its values
+ // to make a decision.
+ Enabled(context.Context, Level) bool
+
+ // Handle handles the Record.
+ // It will only be called when Enabled returns true.
+ // The Context argument is as for Enabled.
+ // It is present solely to provide Handlers access to the context's values.
+ // Canceling the context should not affect record processing.
+ // (Among other things, log messages may be necessary to debug a
+ // cancellation-related problem.)
+ //
+ // Handle methods that produce output should observe the following rules:
+ // - If r.Time is the zero time, ignore the time.
+ // - If r.PC is zero, ignore it.
+ // - Attr's values should be resolved.
+ // - If an Attr's key and value are both the zero value, ignore the Attr.
+ // This can be tested with attr.Equal(Attr{}).
+ // - If a group's key is empty, inline the group's Attrs.
+ // - If a group has no Attrs (even if it has a non-empty key),
+ // ignore it.
+ Handle(context.Context, Record) error
+
+ // WithAttrs returns a new Handler whose attributes consist of
+ // both the receiver's attributes and the arguments.
+ // The Handler owns the slice: it may retain, modify or discard it.
+ WithAttrs(attrs []Attr) Handler
+
+ // WithGroup returns a new Handler with the given group appended to
+ // the receiver's existing groups.
+ // The keys of all subsequent attributes, whether added by With or in a
+ // Record, should be qualified by the sequence of group names.
+ //
+ // How this qualification happens is up to the Handler, so long as
+ // this Handler's attribute keys differ from those of another Handler
+ // with a different sequence of group names.
+ //
+ // A Handler should treat WithGroup as starting a Group of Attrs that ends
+ // at the end of the log event. That is,
+ //
+ // logger.WithGroup("s").LogAttrs(level, msg, slog.Int("a", 1), slog.Int("b", 2))
+ //
+ // should behave like
+ //
+ // logger.LogAttrs(level, msg, slog.Group("s", slog.Int("a", 1), slog.Int("b", 2)))
+ //
+ // If the name is empty, WithGroup returns the receiver.
+ WithGroup(name string) Handler
+}
+
+type defaultHandler struct {
+ ch *commonHandler
+ // log.Output, except for testing
+ output func(calldepth int, message string) error
+}
+
+func newDefaultHandler(output func(int, string) error) *defaultHandler {
+ return &defaultHandler{
+ ch: &commonHandler{json: false},
+ output: output,
+ }
+}
+
+func (*defaultHandler) Enabled(_ context.Context, l Level) bool {
+ return l >= LevelInfo
+}
+
+// Collect the level, attributes and message in a string and
+// write it with the default log.Logger.
+// Let the log.Logger handle time and file/line.
+func (h *defaultHandler) Handle(ctx context.Context, r Record) error {
+ buf := buffer.New()
+ buf.WriteString(r.Level.String())
+ buf.WriteByte(' ')
+ buf.WriteString(r.Message)
+ state := h.ch.newHandleState(buf, true, " ", nil)
+ defer state.free()
+ state.appendNonBuiltIns(r)
+
+ // skip [h.output, defaultHandler.Handle, handlerWriter.Write, log.Output]
+ return h.output(4, buf.String())
+}
+
+func (h *defaultHandler) WithAttrs(as []Attr) Handler {
+ return &defaultHandler{h.ch.withAttrs(as), h.output}
+}
+
+func (h *defaultHandler) WithGroup(name string) Handler {
+ return &defaultHandler{h.ch.withGroup(name), h.output}
+}
+
+// HandlerOptions are options for a TextHandler or JSONHandler.
+// A zero HandlerOptions consists entirely of default values.
+type HandlerOptions struct {
+ // AddSource causes the handler to compute the source code position
+ // of the log statement and add a SourceKey attribute to the output.
+ AddSource bool
+
+ // Level reports the minimum record level that will be logged.
+ // The handler discards records with lower levels.
+ // If Level is nil, the handler assumes LevelInfo.
+ // The handler calls Level.Level for each record processed;
+ // to adjust the minimum level dynamically, use a LevelVar.
+ Level Leveler
+
+ // ReplaceAttr is called to rewrite each non-group attribute before it is logged.
+ // The attribute's value has been resolved (see [Value.Resolve]).
+ // If ReplaceAttr returns an Attr with Key == "", the attribute is discarded.
+ //
+ // The built-in attributes with keys "time", "level", "source", and "msg"
+ // are passed to this function, except that time is omitted
+ // if zero, and source is omitted if AddSource is false.
+ //
+ // The first argument is a list of currently open groups that contain the
+ // Attr. It must not be retained or modified. ReplaceAttr is never called
+ // for Group attributes, only their contents. For example, the attribute
+ // list
+ //
+ // Int("a", 1), Group("g", Int("b", 2)), Int("c", 3)
+ //
+ // results in consecutive calls to ReplaceAttr with the following arguments:
+ //
+ // nil, Int("a", 1)
+ // []string{"g"}, Int("b", 2)
+ // nil, Int("c", 3)
+ //
+ // ReplaceAttr can be used to change the default keys of the built-in
+ // attributes, convert types (for example, to replace a `time.Time` with the
+ // integer seconds since the Unix epoch), sanitize personal information, or
+ // remove attributes from the output.
+ ReplaceAttr func(groups []string, a Attr) Attr
+}
+
+// Keys for "built-in" attributes.
+const (
+ // TimeKey is the key used by the built-in handlers for the time
+ // when the log method is called. The associated Value is a [time.Time].
+ TimeKey = "time"
+ // LevelKey is the key used by the built-in handlers for the level
+ // of the log call. The associated value is a [Level].
+ LevelKey = "level"
+ // MessageKey is the key used by the built-in handlers for the
+ // message of the log call. The associated value is a string.
+ MessageKey = "msg"
+ // SourceKey is the key used by the built-in handlers for the source file
+ // and line of the log call. The associated value is a string.
+ SourceKey = "source"
+)
+
+type commonHandler struct {
+ json bool // true => output JSON; false => output text
+ opts HandlerOptions
+ preformattedAttrs []byte
+ groupPrefix string // for text: prefix of groups opened in preformatting
+ groups []string // all groups started from WithGroup
+ nOpenGroups int // the number of groups opened in preformattedAttrs
+ mu sync.Mutex
+ w io.Writer
+}
+
+func (h *commonHandler) clone() *commonHandler {
+ // We can't use assignment because we can't copy the mutex.
+ return &commonHandler{
+ json: h.json,
+ opts: h.opts,
+ preformattedAttrs: slices.Clip(h.preformattedAttrs),
+ groupPrefix: h.groupPrefix,
+ groups: slices.Clip(h.groups),
+ nOpenGroups: h.nOpenGroups,
+ w: h.w,
+ }
+}
+
+// enabled reports whether l is greater than or equal to the
+// minimum level.
+func (h *commonHandler) enabled(l Level) bool {
+ minLevel := LevelInfo
+ if h.opts.Level != nil {
+ minLevel = h.opts.Level.Level()
+ }
+ return l >= minLevel
+}
+
+func (h *commonHandler) withAttrs(as []Attr) *commonHandler {
+ h2 := h.clone()
+ // Pre-format the attributes as an optimization.
+ prefix := buffer.New()
+ defer prefix.Free()
+ prefix.WriteString(h.groupPrefix)
+ state := h2.newHandleState((*buffer.Buffer)(&h2.preformattedAttrs), false, "", prefix)
+ defer state.free()
+ if len(h2.preformattedAttrs) > 0 {
+ state.sep = h.attrSep()
+ }
+ state.openGroups()
+ for _, a := range as {
+ state.appendAttr(a)
+ }
+ // Remember the new prefix for later keys.
+ h2.groupPrefix = state.prefix.String()
+ // Remember how many opened groups are in preformattedAttrs,
+ // so we don't open them again when we handle a Record.
+ h2.nOpenGroups = len(h2.groups)
+ return h2
+}
+
+func (h *commonHandler) withGroup(name string) *commonHandler {
+ if name == "" {
+ return h
+ }
+ h2 := h.clone()
+ h2.groups = append(h2.groups, name)
+ return h2
+}
+
+func (h *commonHandler) handle(r Record) error {
+ state := h.newHandleState(buffer.New(), true, "", nil)
+ defer state.free()
+ if h.json {
+ state.buf.WriteByte('{')
+ }
+ // Built-in attributes. They are not in a group.
+ stateGroups := state.groups
+ state.groups = nil // So ReplaceAttrs sees no groups instead of the pre groups.
+ rep := h.opts.ReplaceAttr
+ // time
+ if !r.Time.IsZero() {
+ key := TimeKey
+ val := r.Time.Round(0) // strip monotonic to match Attr behavior
+ if rep == nil {
+ state.appendKey(key)
+ state.appendTime(val)
+ } else {
+ state.appendAttr(Time(key, val))
+ }
+ }
+ // level
+ key := LevelKey
+ val := r.Level
+ if rep == nil {
+ state.appendKey(key)
+ state.appendString(val.String())
+ } else {
+ state.appendAttr(Any(key, val))
+ }
+ // source
+ if h.opts.AddSource {
+ state.appendAttr(Any(SourceKey, r.source()))
+ }
+ key = MessageKey
+ msg := r.Message
+ if rep == nil {
+ state.appendKey(key)
+ state.appendString(msg)
+ } else {
+ state.appendAttr(String(key, msg))
+ }
+ state.groups = stateGroups // Restore groups passed to ReplaceAttrs.
+ state.appendNonBuiltIns(r)
+ state.buf.WriteByte('\n')
+
+ h.mu.Lock()
+ defer h.mu.Unlock()
+ _, err := h.w.Write(*state.buf)
+ return err
+}
+
+func (s *handleState) appendNonBuiltIns(r Record) {
+ // preformatted Attrs
+ if len(s.h.preformattedAttrs) > 0 {
+ s.buf.WriteString(s.sep)
+ s.buf.Write(s.h.preformattedAttrs)
+ s.sep = s.h.attrSep()
+ }
+ // Attrs in Record -- unlike the built-in ones, they are in groups started
+ // from WithGroup.
+ s.prefix = buffer.New()
+ defer s.prefix.Free()
+ s.prefix.WriteString(s.h.groupPrefix)
+ s.openGroups()
+ r.Attrs(func(a Attr) bool {
+ s.appendAttr(a)
+ return true
+ })
+ if s.h.json {
+ // Close all open groups.
+ for range s.h.groups {
+ s.buf.WriteByte('}')
+ }
+ // Close the top-level object.
+ s.buf.WriteByte('}')
+ }
+}
+
+// attrSep returns the separator between attributes.
+func (h *commonHandler) attrSep() string {
+ if h.json {
+ return ","
+ }
+ return " "
+}
+
+// handleState holds state for a single call to commonHandler.handle.
+// The initial value of sep determines whether to emit a separator
+// before the next key, after which it stays true.
+type handleState struct {
+ h *commonHandler
+ buf *buffer.Buffer
+ freeBuf bool // should buf be freed?
+ sep string // separator to write before next key
+ prefix *buffer.Buffer // for text: key prefix
+ groups *[]string // pool-allocated slice of active groups, for ReplaceAttr
+}
+
+var groupPool = sync.Pool{New: func() any {
+ s := make([]string, 0, 10)
+ return &s
+}}
+
+func (h *commonHandler) newHandleState(buf *buffer.Buffer, freeBuf bool, sep string, prefix *buffer.Buffer) handleState {
+ s := handleState{
+ h: h,
+ buf: buf,
+ freeBuf: freeBuf,
+ sep: sep,
+ prefix: prefix,
+ }
+ if h.opts.ReplaceAttr != nil {
+ s.groups = groupPool.Get().(*[]string)
+ *s.groups = append(*s.groups, h.groups[:h.nOpenGroups]...)
+ }
+ return s
+}
+
+func (s *handleState) free() {
+ if s.freeBuf {
+ s.buf.Free()
+ }
+ if gs := s.groups; gs != nil {
+ *gs = (*gs)[:0]
+ groupPool.Put(gs)
+ }
+}
+
+func (s *handleState) openGroups() {
+ for _, n := range s.h.groups[s.h.nOpenGroups:] {
+ s.openGroup(n)
+ }
+}
+
+// Separator for group names and keys.
+const keyComponentSep = '.'
+
+// openGroup starts a new group of attributes
+// with the given name.
+func (s *handleState) openGroup(name string) {
+ if s.h.json {
+ s.appendKey(name)
+ s.buf.WriteByte('{')
+ s.sep = ""
+ } else {
+ s.prefix.WriteString(name)
+ s.prefix.WriteByte(keyComponentSep)
+ }
+ // Collect group names for ReplaceAttr.
+ if s.groups != nil {
+ *s.groups = append(*s.groups, name)
+ }
+}
+
+// closeGroup ends the group with the given name.
+func (s *handleState) closeGroup(name string) {
+ if s.h.json {
+ s.buf.WriteByte('}')
+ } else {
+ (*s.prefix) = (*s.prefix)[:len(*s.prefix)-len(name)-1 /* for keyComponentSep */]
+ }
+ s.sep = s.h.attrSep()
+ if s.groups != nil {
+ *s.groups = (*s.groups)[:len(*s.groups)-1]
+ }
+}
+
+// appendAttr appends the Attr's key and value using app.
+// It handles replacement and checking for an empty key.
+// after replacement).
+func (s *handleState) appendAttr(a Attr) {
+ if rep := s.h.opts.ReplaceAttr; rep != nil && a.Value.Kind() != KindGroup {
+ var gs []string
+ if s.groups != nil {
+ gs = *s.groups
+ }
+ // Resolve before calling ReplaceAttr, so the user doesn't have to.
+ a.Value = a.Value.Resolve()
+ a = rep(gs, a)
+ }
+ a.Value = a.Value.Resolve()
+ // Elide empty Attrs.
+ if a.isEmpty() {
+ return
+ }
+ // Special case: Source.
+ if v := a.Value; v.Kind() == KindAny {
+ if src, ok := v.Any().(*Source); ok {
+ if s.h.json {
+ a.Value = src.group()
+ } else {
+ a.Value = StringValue(fmt.Sprintf("%s:%d", src.File, src.Line))
+ }
+ }
+ }
+ if a.Value.Kind() == KindGroup {
+ attrs := a.Value.Group()
+ // Output only non-empty groups.
+ if len(attrs) > 0 {
+ // Inline a group with an empty key.
+ if a.Key != "" {
+ s.openGroup(a.Key)
+ }
+ for _, aa := range attrs {
+ s.appendAttr(aa)
+ }
+ if a.Key != "" {
+ s.closeGroup(a.Key)
+ }
+ }
+ } else {
+ s.appendKey(a.Key)
+ s.appendValue(a.Value)
+ }
+}
+
+func (s *handleState) appendError(err error) {
+ s.appendString(fmt.Sprintf("!ERROR:%v", err))
+}
+
+func (s *handleState) appendKey(key string) {
+ s.buf.WriteString(s.sep)
+ if s.prefix != nil {
+ // TODO: optimize by avoiding allocation.
+ s.appendString(string(*s.prefix) + key)
+ } else {
+ s.appendString(key)
+ }
+ if s.h.json {
+ s.buf.WriteByte(':')
+ } else {
+ s.buf.WriteByte('=')
+ }
+ s.sep = s.h.attrSep()
+}
+
+func (s *handleState) appendString(str string) {
+ if s.h.json {
+ s.buf.WriteByte('"')
+ *s.buf = appendEscapedJSONString(*s.buf, str)
+ s.buf.WriteByte('"')
+ } else {
+ // text
+ if needsQuoting(str) {
+ *s.buf = strconv.AppendQuote(*s.buf, str)
+ } else {
+ s.buf.WriteString(str)
+ }
+ }
+}
+
+func (s *handleState) appendValue(v Value) {
+ defer func() {
+ if r := recover(); r != nil {
+ // If it panics with a nil pointer, the most likely cases are
+ // an encoding.TextMarshaler or error fails to guard against nil,
+ // in which case "" seems to be the feasible choice.
+ //
+ // Adapted from the code in fmt/print.go.
+ if v := reflect.ValueOf(v.any); v.Kind() == reflect.Pointer && v.IsNil() {
+ s.appendString("")
+ return
+ }
+
+ // Otherwise just print the original panic message.
+ s.appendString(fmt.Sprintf("!PANIC: %v", r))
+ }
+ }()
+
+ var err error
+ if s.h.json {
+ err = appendJSONValue(s, v)
+ } else {
+ err = appendTextValue(s, v)
+ }
+ if err != nil {
+ s.appendError(err)
+ }
+}
+
+func (s *handleState) appendTime(t time.Time) {
+ if s.h.json {
+ appendJSONTime(s, t)
+ } else {
+ writeTimeRFC3339Millis(s.buf, t)
+ }
+}
+
+// This takes half the time of Time.AppendFormat.
+func writeTimeRFC3339Millis(buf *buffer.Buffer, t time.Time) {
+ year, month, day := t.Date()
+ buf.WritePosIntWidth(year, 4)
+ buf.WriteByte('-')
+ buf.WritePosIntWidth(int(month), 2)
+ buf.WriteByte('-')
+ buf.WritePosIntWidth(day, 2)
+ buf.WriteByte('T')
+ hour, min, sec := t.Clock()
+ buf.WritePosIntWidth(hour, 2)
+ buf.WriteByte(':')
+ buf.WritePosIntWidth(min, 2)
+ buf.WriteByte(':')
+ buf.WritePosIntWidth(sec, 2)
+ ns := t.Nanosecond()
+ buf.WriteByte('.')
+ buf.WritePosIntWidth(ns/1e6, 3)
+ _, offsetSeconds := t.Zone()
+ if offsetSeconds == 0 {
+ buf.WriteByte('Z')
+ } else {
+ offsetMinutes := offsetSeconds / 60
+ if offsetMinutes < 0 {
+ buf.WriteByte('-')
+ offsetMinutes = -offsetMinutes
+ } else {
+ buf.WriteByte('+')
+ }
+ buf.WritePosIntWidth(offsetMinutes/60, 2)
+ buf.WriteByte(':')
+ buf.WritePosIntWidth(offsetMinutes%60, 2)
+ }
+}
diff --git a/vendor/golang.org/x/exp/slog/internal/buffer/buffer.go b/vendor/golang.org/x/exp/slog/internal/buffer/buffer.go
new file mode 100644
index 000000000..7786c166e
--- /dev/null
+++ b/vendor/golang.org/x/exp/slog/internal/buffer/buffer.go
@@ -0,0 +1,84 @@
+// Copyright 2022 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.
+
+// Package buffer provides a pool-allocated byte buffer.
+package buffer
+
+import (
+ "sync"
+)
+
+// Buffer adapted from go/src/fmt/print.go
+type Buffer []byte
+
+// Having an initial size gives a dramatic speedup.
+var bufPool = sync.Pool{
+ New: func() any {
+ b := make([]byte, 0, 1024)
+ return (*Buffer)(&b)
+ },
+}
+
+func New() *Buffer {
+ return bufPool.Get().(*Buffer)
+}
+
+func (b *Buffer) Free() {
+ // To reduce peak allocation, return only smaller buffers to the pool.
+ const maxBufferSize = 16 << 10
+ if cap(*b) <= maxBufferSize {
+ *b = (*b)[:0]
+ bufPool.Put(b)
+ }
+}
+
+func (b *Buffer) Reset() {
+ *b = (*b)[:0]
+}
+
+func (b *Buffer) Write(p []byte) (int, error) {
+ *b = append(*b, p...)
+ return len(p), nil
+}
+
+func (b *Buffer) WriteString(s string) {
+ *b = append(*b, s...)
+}
+
+func (b *Buffer) WriteByte(c byte) {
+ *b = append(*b, c)
+}
+
+func (b *Buffer) WritePosInt(i int) {
+ b.WritePosIntWidth(i, 0)
+}
+
+// WritePosIntWidth writes non-negative integer i to the buffer, padded on the left
+// by zeroes to the given width. Use a width of 0 to omit padding.
+func (b *Buffer) WritePosIntWidth(i, width int) {
+ // Cheap integer to fixed-width decimal ASCII.
+ // Copied from log/log.go.
+
+ if i < 0 {
+ panic("negative int")
+ }
+
+ // Assemble decimal in reverse order.
+ var bb [20]byte
+ bp := len(bb) - 1
+ for i >= 10 || width > 1 {
+ width--
+ q := i / 10
+ bb[bp] = byte('0' + i - q*10)
+ bp--
+ i = q
+ }
+ // i < 10
+ bb[bp] = byte('0' + i)
+ b.Write(bb[bp:])
+}
+
+func (b *Buffer) String() string {
+ return string(*b)
+}
diff --git a/vendor/golang.org/x/exp/slog/internal/ignorepc.go b/vendor/golang.org/x/exp/slog/internal/ignorepc.go
new file mode 100644
index 000000000..d1256426f
--- /dev/null
+++ b/vendor/golang.org/x/exp/slog/internal/ignorepc.go
@@ -0,0 +1,9 @@
+// Copyright 2023 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.
+
+package internal
+
+// If IgnorePC is true, do not invoke runtime.Callers to get the pc.
+// This is solely for benchmarking the slowdown from runtime.Callers.
+var IgnorePC = false
diff --git a/vendor/golang.org/x/exp/slog/json_handler.go b/vendor/golang.org/x/exp/slog/json_handler.go
new file mode 100644
index 000000000..157ada869
--- /dev/null
+++ b/vendor/golang.org/x/exp/slog/json_handler.go
@@ -0,0 +1,336 @@
+// Copyright 2022 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.
+
+package slog
+
+import (
+ "bytes"
+ "context"
+ "encoding/json"
+ "errors"
+ "fmt"
+ "io"
+ "strconv"
+ "time"
+ "unicode/utf8"
+
+ "golang.org/x/exp/slog/internal/buffer"
+)
+
+// JSONHandler is a Handler that writes Records to an io.Writer as
+// line-delimited JSON objects.
+type JSONHandler struct {
+ *commonHandler
+}
+
+// NewJSONHandler creates a JSONHandler that writes to w,
+// using the given options.
+// If opts is nil, the default options are used.
+func NewJSONHandler(w io.Writer, opts *HandlerOptions) *JSONHandler {
+ if opts == nil {
+ opts = &HandlerOptions{}
+ }
+ return &JSONHandler{
+ &commonHandler{
+ json: true,
+ w: w,
+ opts: *opts,
+ },
+ }
+}
+
+// Enabled reports whether the handler handles records at the given level.
+// The handler ignores records whose level is lower.
+func (h *JSONHandler) Enabled(_ context.Context, level Level) bool {
+ return h.commonHandler.enabled(level)
+}
+
+// WithAttrs returns a new JSONHandler whose attributes consists
+// of h's attributes followed by attrs.
+func (h *JSONHandler) WithAttrs(attrs []Attr) Handler {
+ return &JSONHandler{commonHandler: h.commonHandler.withAttrs(attrs)}
+}
+
+func (h *JSONHandler) WithGroup(name string) Handler {
+ return &JSONHandler{commonHandler: h.commonHandler.withGroup(name)}
+}
+
+// Handle formats its argument Record as a JSON object on a single line.
+//
+// If the Record's time is zero, the time is omitted.
+// Otherwise, the key is "time"
+// and the value is output as with json.Marshal.
+//
+// If the Record's level is zero, the level is omitted.
+// Otherwise, the key is "level"
+// and the value of [Level.String] is output.
+//
+// If the AddSource option is set and source information is available,
+// the key is "source"
+// and the value is output as "FILE:LINE".
+//
+// The message's key is "msg".
+//
+// To modify these or other attributes, or remove them from the output, use
+// [HandlerOptions.ReplaceAttr].
+//
+// Values are formatted as with an [encoding/json.Encoder] with SetEscapeHTML(false),
+// with two exceptions.
+//
+// First, an Attr whose Value is of type error is formatted as a string, by
+// calling its Error method. Only errors in Attrs receive this special treatment,
+// not errors embedded in structs, slices, maps or other data structures that
+// are processed by the encoding/json package.
+//
+// Second, an encoding failure does not cause Handle to return an error.
+// Instead, the error message is formatted as a string.
+//
+// Each call to Handle results in a single serialized call to io.Writer.Write.
+func (h *JSONHandler) Handle(_ context.Context, r Record) error {
+ return h.commonHandler.handle(r)
+}
+
+// Adapted from time.Time.MarshalJSON to avoid allocation.
+func appendJSONTime(s *handleState, t time.Time) {
+ if y := t.Year(); y < 0 || y >= 10000 {
+ // RFC 3339 is clear that years are 4 digits exactly.
+ // See golang.org/issue/4556#c15 for more discussion.
+ s.appendError(errors.New("time.Time year outside of range [0,9999]"))
+ }
+ s.buf.WriteByte('"')
+ *s.buf = t.AppendFormat(*s.buf, time.RFC3339Nano)
+ s.buf.WriteByte('"')
+}
+
+func appendJSONValue(s *handleState, v Value) error {
+ switch v.Kind() {
+ case KindString:
+ s.appendString(v.str())
+ case KindInt64:
+ *s.buf = strconv.AppendInt(*s.buf, v.Int64(), 10)
+ case KindUint64:
+ *s.buf = strconv.AppendUint(*s.buf, v.Uint64(), 10)
+ case KindFloat64:
+ // json.Marshal is funny about floats; it doesn't
+ // always match strconv.AppendFloat. So just call it.
+ // That's expensive, but floats are rare.
+ if err := appendJSONMarshal(s.buf, v.Float64()); err != nil {
+ return err
+ }
+ case KindBool:
+ *s.buf = strconv.AppendBool(*s.buf, v.Bool())
+ case KindDuration:
+ // Do what json.Marshal does.
+ *s.buf = strconv.AppendInt(*s.buf, int64(v.Duration()), 10)
+ case KindTime:
+ s.appendTime(v.Time())
+ case KindAny:
+ a := v.Any()
+ _, jm := a.(json.Marshaler)
+ if err, ok := a.(error); ok && !jm {
+ s.appendString(err.Error())
+ } else {
+ return appendJSONMarshal(s.buf, a)
+ }
+ default:
+ panic(fmt.Sprintf("bad kind: %s", v.Kind()))
+ }
+ return nil
+}
+
+func appendJSONMarshal(buf *buffer.Buffer, v any) error {
+ // Use a json.Encoder to avoid escaping HTML.
+ var bb bytes.Buffer
+ enc := json.NewEncoder(&bb)
+ enc.SetEscapeHTML(false)
+ if err := enc.Encode(v); err != nil {
+ return err
+ }
+ bs := bb.Bytes()
+ buf.Write(bs[:len(bs)-1]) // remove final newline
+ return nil
+}
+
+// appendEscapedJSONString escapes s for JSON and appends it to buf.
+// It does not surround the string in quotation marks.
+//
+// Modified from encoding/json/encode.go:encodeState.string,
+// with escapeHTML set to false.
+func appendEscapedJSONString(buf []byte, s string) []byte {
+ char := func(b byte) { buf = append(buf, b) }
+ str := func(s string) { buf = append(buf, s...) }
+
+ start := 0
+ for i := 0; i < len(s); {
+ if b := s[i]; b < utf8.RuneSelf {
+ if safeSet[b] {
+ i++
+ continue
+ }
+ if start < i {
+ str(s[start:i])
+ }
+ char('\\')
+ switch b {
+ case '\\', '"':
+ char(b)
+ case '\n':
+ char('n')
+ case '\r':
+ char('r')
+ case '\t':
+ char('t')
+ default:
+ // This encodes bytes < 0x20 except for \t, \n and \r.
+ str(`u00`)
+ char(hex[b>>4])
+ char(hex[b&0xF])
+ }
+ i++
+ start = i
+ continue
+ }
+ c, size := utf8.DecodeRuneInString(s[i:])
+ if c == utf8.RuneError && size == 1 {
+ if start < i {
+ str(s[start:i])
+ }
+ str(`\ufffd`)
+ i += size
+ start = i
+ continue
+ }
+ // U+2028 is LINE SEPARATOR.
+ // U+2029 is PARAGRAPH SEPARATOR.
+ // They are both technically valid characters in JSON strings,
+ // but don't work in JSONP, which has to be evaluated as JavaScript,
+ // and can lead to security holes there. It is valid JSON to
+ // escape them, so we do so unconditionally.
+ // See http://timelessrepo.com/json-isnt-a-javascript-subset for discussion.
+ if c == '\u2028' || c == '\u2029' {
+ if start < i {
+ str(s[start:i])
+ }
+ str(`\u202`)
+ char(hex[c&0xF])
+ i += size
+ start = i
+ continue
+ }
+ i += size
+ }
+ if start < len(s) {
+ str(s[start:])
+ }
+ return buf
+}
+
+var hex = "0123456789abcdef"
+
+// Copied from encoding/json/tables.go.
+//
+// safeSet holds the value true if the ASCII character with the given array
+// position can be represented inside a JSON string without any further
+// escaping.
+//
+// All values are true except for the ASCII control characters (0-31), the
+// double quote ("), and the backslash character ("\").
+var safeSet = [utf8.RuneSelf]bool{
+ ' ': true,
+ '!': true,
+ '"': false,
+ '#': true,
+ '$': true,
+ '%': true,
+ '&': true,
+ '\'': true,
+ '(': true,
+ ')': true,
+ '*': true,
+ '+': true,
+ ',': true,
+ '-': true,
+ '.': true,
+ '/': true,
+ '0': true,
+ '1': true,
+ '2': true,
+ '3': true,
+ '4': true,
+ '5': true,
+ '6': true,
+ '7': true,
+ '8': true,
+ '9': true,
+ ':': true,
+ ';': true,
+ '<': true,
+ '=': true,
+ '>': true,
+ '?': true,
+ '@': true,
+ 'A': true,
+ 'B': true,
+ 'C': true,
+ 'D': true,
+ 'E': true,
+ 'F': true,
+ 'G': true,
+ 'H': true,
+ 'I': true,
+ 'J': true,
+ 'K': true,
+ 'L': true,
+ 'M': true,
+ 'N': true,
+ 'O': true,
+ 'P': true,
+ 'Q': true,
+ 'R': true,
+ 'S': true,
+ 'T': true,
+ 'U': true,
+ 'V': true,
+ 'W': true,
+ 'X': true,
+ 'Y': true,
+ 'Z': true,
+ '[': true,
+ '\\': false,
+ ']': true,
+ '^': true,
+ '_': true,
+ '`': true,
+ 'a': true,
+ 'b': true,
+ 'c': true,
+ 'd': true,
+ 'e': true,
+ 'f': true,
+ 'g': true,
+ 'h': true,
+ 'i': true,
+ 'j': true,
+ 'k': true,
+ 'l': true,
+ 'm': true,
+ 'n': true,
+ 'o': true,
+ 'p': true,
+ 'q': true,
+ 'r': true,
+ 's': true,
+ 't': true,
+ 'u': true,
+ 'v': true,
+ 'w': true,
+ 'x': true,
+ 'y': true,
+ 'z': true,
+ '{': true,
+ '|': true,
+ '}': true,
+ '~': true,
+ '\u007f': true,
+}
diff --git a/vendor/golang.org/x/exp/slog/level.go b/vendor/golang.org/x/exp/slog/level.go
new file mode 100644
index 000000000..b2365f0aa
--- /dev/null
+++ b/vendor/golang.org/x/exp/slog/level.go
@@ -0,0 +1,201 @@
+// Copyright 2022 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.
+
+package slog
+
+import (
+ "errors"
+ "fmt"
+ "strconv"
+ "strings"
+ "sync/atomic"
+)
+
+// A Level is the importance or severity of a log event.
+// The higher the level, the more important or severe the event.
+type Level int
+
+// Level numbers are inherently arbitrary,
+// but we picked them to satisfy three constraints.
+// Any system can map them to another numbering scheme if it wishes.
+//
+// First, we wanted the default level to be Info, Since Levels are ints, Info is
+// the default value for int, zero.
+//
+
+// Second, we wanted to make it easy to use levels to specify logger verbosity.
+// Since a larger level means a more severe event, a logger that accepts events
+// with smaller (or more negative) level means a more verbose logger. Logger
+// verbosity is thus the negation of event severity, and the default verbosity
+// of 0 accepts all events at least as severe as INFO.
+//
+// Third, we wanted some room between levels to accommodate schemes with named
+// levels between ours. For example, Google Cloud Logging defines a Notice level
+// between Info and Warn. Since there are only a few of these intermediate
+// levels, the gap between the numbers need not be large. Our gap of 4 matches
+// OpenTelemetry's mapping. Subtracting 9 from an OpenTelemetry level in the
+// DEBUG, INFO, WARN and ERROR ranges converts it to the corresponding slog
+// Level range. OpenTelemetry also has the names TRACE and FATAL, which slog
+// does not. But those OpenTelemetry levels can still be represented as slog
+// Levels by using the appropriate integers.
+//
+// Names for common levels.
+const (
+ LevelDebug Level = -4
+ LevelInfo Level = 0
+ LevelWarn Level = 4
+ LevelError Level = 8
+)
+
+// String returns a name for the level.
+// If the level has a name, then that name
+// in uppercase is returned.
+// If the level is between named values, then
+// an integer is appended to the uppercased name.
+// Examples:
+//
+// LevelWarn.String() => "WARN"
+// (LevelInfo+2).String() => "INFO+2"
+func (l Level) String() string {
+ str := func(base string, val Level) string {
+ if val == 0 {
+ return base
+ }
+ return fmt.Sprintf("%s%+d", base, val)
+ }
+
+ switch {
+ case l < LevelInfo:
+ return str("DEBUG", l-LevelDebug)
+ case l < LevelWarn:
+ return str("INFO", l-LevelInfo)
+ case l < LevelError:
+ return str("WARN", l-LevelWarn)
+ default:
+ return str("ERROR", l-LevelError)
+ }
+}
+
+// MarshalJSON implements [encoding/json.Marshaler]
+// by quoting the output of [Level.String].
+func (l Level) MarshalJSON() ([]byte, error) {
+ // AppendQuote is sufficient for JSON-encoding all Level strings.
+ // They don't contain any runes that would produce invalid JSON
+ // when escaped.
+ return strconv.AppendQuote(nil, l.String()), nil
+}
+
+// UnmarshalJSON implements [encoding/json.Unmarshaler]
+// It accepts any string produced by [Level.MarshalJSON],
+// ignoring case.
+// It also accepts numeric offsets that would result in a different string on
+// output. For example, "Error-8" would marshal as "INFO".
+func (l *Level) UnmarshalJSON(data []byte) error {
+ s, err := strconv.Unquote(string(data))
+ if err != nil {
+ return err
+ }
+ return l.parse(s)
+}
+
+// MarshalText implements [encoding.TextMarshaler]
+// by calling [Level.String].
+func (l Level) MarshalText() ([]byte, error) {
+ return []byte(l.String()), nil
+}
+
+// UnmarshalText implements [encoding.TextUnmarshaler].
+// It accepts any string produced by [Level.MarshalText],
+// ignoring case.
+// It also accepts numeric offsets that would result in a different string on
+// output. For example, "Error-8" would marshal as "INFO".
+func (l *Level) UnmarshalText(data []byte) error {
+ return l.parse(string(data))
+}
+
+func (l *Level) parse(s string) (err error) {
+ defer func() {
+ if err != nil {
+ err = fmt.Errorf("slog: level string %q: %w", s, err)
+ }
+ }()
+
+ name := s
+ offset := 0
+ if i := strings.IndexAny(s, "+-"); i >= 0 {
+ name = s[:i]
+ offset, err = strconv.Atoi(s[i:])
+ if err != nil {
+ return err
+ }
+ }
+ switch strings.ToUpper(name) {
+ case "DEBUG":
+ *l = LevelDebug
+ case "INFO":
+ *l = LevelInfo
+ case "WARN":
+ *l = LevelWarn
+ case "ERROR":
+ *l = LevelError
+ default:
+ return errors.New("unknown name")
+ }
+ *l += Level(offset)
+ return nil
+}
+
+// Level returns the receiver.
+// It implements Leveler.
+func (l Level) Level() Level { return l }
+
+// A LevelVar is a Level variable, to allow a Handler level to change
+// dynamically.
+// It implements Leveler as well as a Set method,
+// and it is safe for use by multiple goroutines.
+// The zero LevelVar corresponds to LevelInfo.
+type LevelVar struct {
+ val atomic.Int64
+}
+
+// Level returns v's level.
+func (v *LevelVar) Level() Level {
+ return Level(int(v.val.Load()))
+}
+
+// Set sets v's level to l.
+func (v *LevelVar) Set(l Level) {
+ v.val.Store(int64(l))
+}
+
+func (v *LevelVar) String() string {
+ return fmt.Sprintf("LevelVar(%s)", v.Level())
+}
+
+// MarshalText implements [encoding.TextMarshaler]
+// by calling [Level.MarshalText].
+func (v *LevelVar) MarshalText() ([]byte, error) {
+ return v.Level().MarshalText()
+}
+
+// UnmarshalText implements [encoding.TextUnmarshaler]
+// by calling [Level.UnmarshalText].
+func (v *LevelVar) UnmarshalText(data []byte) error {
+ var l Level
+ if err := l.UnmarshalText(data); err != nil {
+ return err
+ }
+ v.Set(l)
+ return nil
+}
+
+// A Leveler provides a Level value.
+//
+// As Level itself implements Leveler, clients typically supply
+// a Level value wherever a Leveler is needed, such as in HandlerOptions.
+// Clients who need to vary the level dynamically can provide a more complex
+// Leveler implementation such as *LevelVar.
+type Leveler interface {
+ Level() Level
+}
diff --git a/vendor/golang.org/x/exp/slog/logger.go b/vendor/golang.org/x/exp/slog/logger.go
new file mode 100644
index 000000000..e87ec9936
--- /dev/null
+++ b/vendor/golang.org/x/exp/slog/logger.go
@@ -0,0 +1,343 @@
+// Copyright 2022 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.
+
+package slog
+
+import (
+ "context"
+ "log"
+ "runtime"
+ "sync/atomic"
+ "time"
+
+ "golang.org/x/exp/slog/internal"
+)
+
+var defaultLogger atomic.Value
+
+func init() {
+ defaultLogger.Store(New(newDefaultHandler(log.Output)))
+}
+
+// Default returns the default Logger.
+func Default() *Logger { return defaultLogger.Load().(*Logger) }
+
+// SetDefault makes l the default Logger.
+// After this call, output from the log package's default Logger
+// (as with [log.Print], etc.) will be logged at LevelInfo using l's Handler.
+func SetDefault(l *Logger) {
+ defaultLogger.Store(l)
+ // If the default's handler is a defaultHandler, then don't use a handleWriter,
+ // or we'll deadlock as they both try to acquire the log default mutex.
+ // The defaultHandler will use whatever the log default writer is currently
+ // set to, which is correct.
+ // This can occur with SetDefault(Default()).
+ // See TestSetDefault.
+ if _, ok := l.Handler().(*defaultHandler); !ok {
+ capturePC := log.Flags()&(log.Lshortfile|log.Llongfile) != 0
+ log.SetOutput(&handlerWriter{l.Handler(), LevelInfo, capturePC})
+ log.SetFlags(0) // we want just the log message, no time or location
+ }
+}
+
+// handlerWriter is an io.Writer that calls a Handler.
+// It is used to link the default log.Logger to the default slog.Logger.
+type handlerWriter struct {
+ h Handler
+ level Level
+ capturePC bool
+}
+
+func (w *handlerWriter) Write(buf []byte) (int, error) {
+ if !w.h.Enabled(context.Background(), w.level) {
+ return 0, nil
+ }
+ var pc uintptr
+ if !internal.IgnorePC && w.capturePC {
+ // skip [runtime.Callers, w.Write, Logger.Output, log.Print]
+ var pcs [1]uintptr
+ runtime.Callers(4, pcs[:])
+ pc = pcs[0]
+ }
+
+ // Remove final newline.
+ origLen := len(buf) // Report that the entire buf was written.
+ if len(buf) > 0 && buf[len(buf)-1] == '\n' {
+ buf = buf[:len(buf)-1]
+ }
+ r := NewRecord(time.Now(), w.level, string(buf), pc)
+ return origLen, w.h.Handle(context.Background(), r)
+}
+
+// A Logger records structured information about each call to its
+// Log, Debug, Info, Warn, and Error methods.
+// For each call, it creates a Record and passes it to a Handler.
+//
+// To create a new Logger, call [New] or a Logger method
+// that begins "With".
+type Logger struct {
+ handler Handler // for structured logging
+}
+
+func (l *Logger) clone() *Logger {
+ c := *l
+ return &c
+}
+
+// Handler returns l's Handler.
+func (l *Logger) Handler() Handler { return l.handler }
+
+// With returns a new Logger that includes the given arguments, converted to
+// Attrs as in [Logger.Log].
+// The Attrs will be added to each output from the Logger.
+// The new Logger shares the old Logger's context.
+// The new Logger's handler is the result of calling WithAttrs on the receiver's
+// handler.
+func (l *Logger) With(args ...any) *Logger {
+ c := l.clone()
+ c.handler = l.handler.WithAttrs(argsToAttrSlice(args))
+ return c
+}
+
+// WithGroup returns a new Logger that starts a group. The keys of all
+// attributes added to the Logger will be qualified by the given name.
+// (How that qualification happens depends on the [Handler.WithGroup]
+// method of the Logger's Handler.)
+// The new Logger shares the old Logger's context.
+//
+// The new Logger's handler is the result of calling WithGroup on the receiver's
+// handler.
+func (l *Logger) WithGroup(name string) *Logger {
+ c := l.clone()
+ c.handler = l.handler.WithGroup(name)
+ return c
+
+}
+
+// New creates a new Logger with the given non-nil Handler and a nil context.
+func New(h Handler) *Logger {
+ if h == nil {
+ panic("nil Handler")
+ }
+ return &Logger{handler: h}
+}
+
+// With calls Logger.With on the default logger.
+func With(args ...any) *Logger {
+ return Default().With(args...)
+}
+
+// Enabled reports whether l emits log records at the given context and level.
+func (l *Logger) Enabled(ctx context.Context, level Level) bool {
+ if ctx == nil {
+ ctx = context.Background()
+ }
+ return l.Handler().Enabled(ctx, level)
+}
+
+// NewLogLogger returns a new log.Logger such that each call to its Output method
+// dispatches a Record to the specified handler. The logger acts as a bridge from
+// the older log API to newer structured logging handlers.
+func NewLogLogger(h Handler, level Level) *log.Logger {
+ return log.New(&handlerWriter{h, level, true}, "", 0)
+}
+
+// Log emits a log record with the current time and the given level and message.
+// The Record's Attrs consist of the Logger's attributes followed by
+// the Attrs specified by args.
+//
+// The attribute arguments are processed as follows:
+// - If an argument is an Attr, it is used as is.
+// - If an argument is a string and this is not the last argument,
+// the following argument is treated as the value and the two are combined
+// into an Attr.
+// - Otherwise, the argument is treated as a value with key "!BADKEY".
+func (l *Logger) Log(ctx context.Context, level Level, msg string, args ...any) {
+ l.log(ctx, level, msg, args...)
+}
+
+// LogAttrs is a more efficient version of [Logger.Log] that accepts only Attrs.
+func (l *Logger) LogAttrs(ctx context.Context, level Level, msg string, attrs ...Attr) {
+ l.logAttrs(ctx, level, msg, attrs...)
+}
+
+// Debug logs at LevelDebug.
+func (l *Logger) Debug(msg string, args ...any) {
+ l.log(nil, LevelDebug, msg, args...)
+}
+
+// DebugContext logs at LevelDebug with the given context.
+func (l *Logger) DebugContext(ctx context.Context, msg string, args ...any) {
+ l.log(ctx, LevelDebug, msg, args...)
+}
+
+// DebugCtx logs at LevelDebug with the given context.
+// Deprecated: Use Logger.DebugContext.
+func (l *Logger) DebugCtx(ctx context.Context, msg string, args ...any) {
+ l.log(ctx, LevelDebug, msg, args...)
+}
+
+// Info logs at LevelInfo.
+func (l *Logger) Info(msg string, args ...any) {
+ l.log(nil, LevelInfo, msg, args...)
+}
+
+// InfoContext logs at LevelInfo with the given context.
+func (l *Logger) InfoContext(ctx context.Context, msg string, args ...any) {
+ l.log(ctx, LevelInfo, msg, args...)
+}
+
+// InfoCtx logs at LevelInfo with the given context.
+// Deprecated: Use Logger.InfoContext.
+func (l *Logger) InfoCtx(ctx context.Context, msg string, args ...any) {
+ l.log(ctx, LevelInfo, msg, args...)
+}
+
+// Warn logs at LevelWarn.
+func (l *Logger) Warn(msg string, args ...any) {
+ l.log(nil, LevelWarn, msg, args...)
+}
+
+// WarnContext logs at LevelWarn with the given context.
+func (l *Logger) WarnContext(ctx context.Context, msg string, args ...any) {
+ l.log(ctx, LevelWarn, msg, args...)
+}
+
+// WarnCtx logs at LevelWarn with the given context.
+// Deprecated: Use Logger.WarnContext.
+func (l *Logger) WarnCtx(ctx context.Context, msg string, args ...any) {
+ l.log(ctx, LevelWarn, msg, args...)
+}
+
+// Error logs at LevelError.
+func (l *Logger) Error(msg string, args ...any) {
+ l.log(nil, LevelError, msg, args...)
+}
+
+// ErrorContext logs at LevelError with the given context.
+func (l *Logger) ErrorContext(ctx context.Context, msg string, args ...any) {
+ l.log(ctx, LevelError, msg, args...)
+}
+
+// ErrorCtx logs at LevelError with the given context.
+// Deprecated: Use Logger.ErrorContext.
+func (l *Logger) ErrorCtx(ctx context.Context, msg string, args ...any) {
+ l.log(ctx, LevelError, msg, args...)
+}
+
+// log is the low-level logging method for methods that take ...any.
+// It must always be called directly by an exported logging method
+// or function, because it uses a fixed call depth to obtain the pc.
+func (l *Logger) log(ctx context.Context, level Level, msg string, args ...any) {
+ if !l.Enabled(ctx, level) {
+ return
+ }
+ var pc uintptr
+ if !internal.IgnorePC {
+ var pcs [1]uintptr
+ // skip [runtime.Callers, this function, this function's caller]
+ runtime.Callers(3, pcs[:])
+ pc = pcs[0]
+ }
+ r := NewRecord(time.Now(), level, msg, pc)
+ r.Add(args...)
+ if ctx == nil {
+ ctx = context.Background()
+ }
+ _ = l.Handler().Handle(ctx, r)
+}
+
+// logAttrs is like [Logger.log], but for methods that take ...Attr.
+func (l *Logger) logAttrs(ctx context.Context, level Level, msg string, attrs ...Attr) {
+ if !l.Enabled(ctx, level) {
+ return
+ }
+ var pc uintptr
+ if !internal.IgnorePC {
+ var pcs [1]uintptr
+ // skip [runtime.Callers, this function, this function's caller]
+ runtime.Callers(3, pcs[:])
+ pc = pcs[0]
+ }
+ r := NewRecord(time.Now(), level, msg, pc)
+ r.AddAttrs(attrs...)
+ if ctx == nil {
+ ctx = context.Background()
+ }
+ _ = l.Handler().Handle(ctx, r)
+}
+
+// Debug calls Logger.Debug on the default logger.
+func Debug(msg string, args ...any) {
+ Default().log(nil, LevelDebug, msg, args...)
+}
+
+// DebugContext calls Logger.DebugContext on the default logger.
+func DebugContext(ctx context.Context, msg string, args ...any) {
+ Default().log(ctx, LevelDebug, msg, args...)
+}
+
+// Info calls Logger.Info on the default logger.
+func Info(msg string, args ...any) {
+ Default().log(nil, LevelInfo, msg, args...)
+}
+
+// InfoContext calls Logger.InfoContext on the default logger.
+func InfoContext(ctx context.Context, msg string, args ...any) {
+ Default().log(ctx, LevelInfo, msg, args...)
+}
+
+// Warn calls Logger.Warn on the default logger.
+func Warn(msg string, args ...any) {
+ Default().log(nil, LevelWarn, msg, args...)
+}
+
+// WarnContext calls Logger.WarnContext on the default logger.
+func WarnContext(ctx context.Context, msg string, args ...any) {
+ Default().log(ctx, LevelWarn, msg, args...)
+}
+
+// Error calls Logger.Error on the default logger.
+func Error(msg string, args ...any) {
+ Default().log(nil, LevelError, msg, args...)
+}
+
+// ErrorContext calls Logger.ErrorContext on the default logger.
+func ErrorContext(ctx context.Context, msg string, args ...any) {
+ Default().log(ctx, LevelError, msg, args...)
+}
+
+// DebugCtx calls Logger.DebugContext on the default logger.
+// Deprecated: call DebugContext.
+func DebugCtx(ctx context.Context, msg string, args ...any) {
+ Default().log(ctx, LevelDebug, msg, args...)
+}
+
+// InfoCtx calls Logger.InfoContext on the default logger.
+// Deprecated: call InfoContext.
+func InfoCtx(ctx context.Context, msg string, args ...any) {
+ Default().log(ctx, LevelInfo, msg, args...)
+}
+
+// WarnCtx calls Logger.WarnContext on the default logger.
+// Deprecated: call WarnContext.
+func WarnCtx(ctx context.Context, msg string, args ...any) {
+ Default().log(ctx, LevelWarn, msg, args...)
+}
+
+// ErrorCtx calls Logger.ErrorContext on the default logger.
+// Deprecated: call ErrorContext.
+func ErrorCtx(ctx context.Context, msg string, args ...any) {
+ Default().log(ctx, LevelError, msg, args...)
+}
+
+// Log calls Logger.Log on the default logger.
+func Log(ctx context.Context, level Level, msg string, args ...any) {
+ Default().log(ctx, level, msg, args...)
+}
+
+// LogAttrs calls Logger.LogAttrs on the default logger.
+func LogAttrs(ctx context.Context, level Level, msg string, attrs ...Attr) {
+ Default().logAttrs(ctx, level, msg, attrs...)
+}
diff --git a/vendor/golang.org/x/exp/slog/noplog.bench b/vendor/golang.org/x/exp/slog/noplog.bench
new file mode 100644
index 000000000..ed9296ff6
--- /dev/null
+++ b/vendor/golang.org/x/exp/slog/noplog.bench
@@ -0,0 +1,36 @@
+goos: linux
+goarch: amd64
+pkg: golang.org/x/exp/slog
+cpu: Intel(R) Xeon(R) CPU @ 2.20GHz
+BenchmarkNopLog/attrs-8 1000000 1090 ns/op 0 B/op 0 allocs/op
+BenchmarkNopLog/attrs-8 1000000 1097 ns/op 0 B/op 0 allocs/op
+BenchmarkNopLog/attrs-8 1000000 1078 ns/op 0 B/op 0 allocs/op
+BenchmarkNopLog/attrs-8 1000000 1095 ns/op 0 B/op 0 allocs/op
+BenchmarkNopLog/attrs-8 1000000 1096 ns/op 0 B/op 0 allocs/op
+BenchmarkNopLog/attrs-parallel-8 4007268 308.2 ns/op 0 B/op 0 allocs/op
+BenchmarkNopLog/attrs-parallel-8 4016138 299.7 ns/op 0 B/op 0 allocs/op
+BenchmarkNopLog/attrs-parallel-8 4020529 305.9 ns/op 0 B/op 0 allocs/op
+BenchmarkNopLog/attrs-parallel-8 3977829 303.4 ns/op 0 B/op 0 allocs/op
+BenchmarkNopLog/attrs-parallel-8 3225438 318.5 ns/op 0 B/op 0 allocs/op
+BenchmarkNopLog/keys-values-8 1179256 994.2 ns/op 0 B/op 0 allocs/op
+BenchmarkNopLog/keys-values-8 1000000 1002 ns/op 0 B/op 0 allocs/op
+BenchmarkNopLog/keys-values-8 1216710 993.2 ns/op 0 B/op 0 allocs/op
+BenchmarkNopLog/keys-values-8 1000000 1013 ns/op 0 B/op 0 allocs/op
+BenchmarkNopLog/keys-values-8 1000000 1016 ns/op 0 B/op 0 allocs/op
+BenchmarkNopLog/WithContext-8 989066 1163 ns/op 0 B/op 0 allocs/op
+BenchmarkNopLog/WithContext-8 994116 1163 ns/op 0 B/op 0 allocs/op
+BenchmarkNopLog/WithContext-8 1000000 1152 ns/op 0 B/op 0 allocs/op
+BenchmarkNopLog/WithContext-8 991675 1165 ns/op 0 B/op 0 allocs/op
+BenchmarkNopLog/WithContext-8 965268 1166 ns/op 0 B/op 0 allocs/op
+BenchmarkNopLog/WithContext-parallel-8 3955503 303.3 ns/op 0 B/op 0 allocs/op
+BenchmarkNopLog/WithContext-parallel-8 3861188 307.8 ns/op 0 B/op 0 allocs/op
+BenchmarkNopLog/WithContext-parallel-8 3967752 303.9 ns/op 0 B/op 0 allocs/op
+BenchmarkNopLog/WithContext-parallel-8 3955203 302.7 ns/op 0 B/op 0 allocs/op
+BenchmarkNopLog/WithContext-parallel-8 3948278 301.1 ns/op 0 B/op 0 allocs/op
+BenchmarkNopLog/Ctx-8 940622 1247 ns/op 0 B/op 0 allocs/op
+BenchmarkNopLog/Ctx-8 936381 1257 ns/op 0 B/op 0 allocs/op
+BenchmarkNopLog/Ctx-8 959730 1266 ns/op 0 B/op 0 allocs/op
+BenchmarkNopLog/Ctx-8 943473 1290 ns/op 0 B/op 0 allocs/op
+BenchmarkNopLog/Ctx-8 919414 1259 ns/op 0 B/op 0 allocs/op
+PASS
+ok golang.org/x/exp/slog 40.566s
diff --git a/vendor/golang.org/x/exp/slog/record.go b/vendor/golang.org/x/exp/slog/record.go
new file mode 100644
index 000000000..38b3440f7
--- /dev/null
+++ b/vendor/golang.org/x/exp/slog/record.go
@@ -0,0 +1,207 @@
+// Copyright 2022 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.
+
+package slog
+
+import (
+ "runtime"
+ "time"
+
+ "golang.org/x/exp/slices"
+)
+
+const nAttrsInline = 5
+
+// A Record holds information about a log event.
+// Copies of a Record share state.
+// Do not modify a Record after handing out a copy to it.
+// Use [Record.Clone] to create a copy with no shared state.
+type Record struct {
+ // The time at which the output method (Log, Info, etc.) was called.
+ Time time.Time
+
+ // The log message.
+ Message string
+
+ // The level of the event.
+ Level Level
+
+ // The program counter at the time the record was constructed, as determined
+ // by runtime.Callers. If zero, no program counter is available.
+ //
+ // The only valid use for this value is as an argument to
+ // [runtime.CallersFrames]. In particular, it must not be passed to
+ // [runtime.FuncForPC].
+ PC uintptr
+
+ // Allocation optimization: an inline array sized to hold
+ // the majority of log calls (based on examination of open-source
+ // code). It holds the start of the list of Attrs.
+ front [nAttrsInline]Attr
+
+ // The number of Attrs in front.
+ nFront int
+
+ // The list of Attrs except for those in front.
+ // Invariants:
+ // - len(back) > 0 iff nFront == len(front)
+ // - Unused array elements are zero. Used to detect mistakes.
+ back []Attr
+}
+
+// NewRecord creates a Record from the given arguments.
+// Use [Record.AddAttrs] to add attributes to the Record.
+//
+// NewRecord is intended for logging APIs that want to support a [Handler] as
+// a backend.
+func NewRecord(t time.Time, level Level, msg string, pc uintptr) Record {
+ return Record{
+ Time: t,
+ Message: msg,
+ Level: level,
+ PC: pc,
+ }
+}
+
+// Clone returns a copy of the record with no shared state.
+// The original record and the clone can both be modified
+// without interfering with each other.
+func (r Record) Clone() Record {
+ r.back = slices.Clip(r.back) // prevent append from mutating shared array
+ return r
+}
+
+// NumAttrs returns the number of attributes in the Record.
+func (r Record) NumAttrs() int {
+ return r.nFront + len(r.back)
+}
+
+// Attrs calls f on each Attr in the Record.
+// Iteration stops if f returns false.
+func (r Record) Attrs(f func(Attr) bool) {
+ for i := 0; i < r.nFront; i++ {
+ if !f(r.front[i]) {
+ return
+ }
+ }
+ for _, a := range r.back {
+ if !f(a) {
+ return
+ }
+ }
+}
+
+// AddAttrs appends the given Attrs to the Record's list of Attrs.
+func (r *Record) AddAttrs(attrs ...Attr) {
+ n := copy(r.front[r.nFront:], attrs)
+ r.nFront += n
+ // Check if a copy was modified by slicing past the end
+ // and seeing if the Attr there is non-zero.
+ if cap(r.back) > len(r.back) {
+ end := r.back[:len(r.back)+1][len(r.back)]
+ if !end.isEmpty() {
+ panic("copies of a slog.Record were both modified")
+ }
+ }
+ r.back = append(r.back, attrs[n:]...)
+}
+
+// Add converts the args to Attrs as described in [Logger.Log],
+// then appends the Attrs to the Record's list of Attrs.
+func (r *Record) Add(args ...any) {
+ var a Attr
+ for len(args) > 0 {
+ a, args = argsToAttr(args)
+ if r.nFront < len(r.front) {
+ r.front[r.nFront] = a
+ r.nFront++
+ } else {
+ if r.back == nil {
+ r.back = make([]Attr, 0, countAttrs(args))
+ }
+ r.back = append(r.back, a)
+ }
+ }
+
+}
+
+// countAttrs returns the number of Attrs that would be created from args.
+func countAttrs(args []any) int {
+ n := 0
+ for i := 0; i < len(args); i++ {
+ n++
+ if _, ok := args[i].(string); ok {
+ i++
+ }
+ }
+ return n
+}
+
+const badKey = "!BADKEY"
+
+// argsToAttr turns a prefix of the nonempty args slice into an Attr
+// and returns the unconsumed portion of the slice.
+// If args[0] is an Attr, it returns it.
+// If args[0] is a string, it treats the first two elements as
+// a key-value pair.
+// Otherwise, it treats args[0] as a value with a missing key.
+func argsToAttr(args []any) (Attr, []any) {
+ switch x := args[0].(type) {
+ case string:
+ if len(args) == 1 {
+ return String(badKey, x), nil
+ }
+ return Any(x, args[1]), args[2:]
+
+ case Attr:
+ return x, args[1:]
+
+ default:
+ return Any(badKey, x), args[1:]
+ }
+}
+
+// Source describes the location of a line of source code.
+type Source struct {
+ // Function is the package path-qualified function name containing the
+ // source line. If non-empty, this string uniquely identifies a single
+ // function in the program. This may be the empty string if not known.
+ Function string `json:"function"`
+ // File and Line are the file name and line number (1-based) of the source
+ // line. These may be the empty string and zero, respectively, if not known.
+ File string `json:"file"`
+ Line int `json:"line"`
+}
+
+// attrs returns the non-zero fields of s as a slice of attrs.
+// It is similar to a LogValue method, but we don't want Source
+// to implement LogValuer because it would be resolved before
+// the ReplaceAttr function was called.
+func (s *Source) group() Value {
+ var as []Attr
+ if s.Function != "" {
+ as = append(as, String("function", s.Function))
+ }
+ if s.File != "" {
+ as = append(as, String("file", s.File))
+ }
+ if s.Line != 0 {
+ as = append(as, Int("line", s.Line))
+ }
+ return GroupValue(as...)
+}
+
+// source returns a Source for the log event.
+// If the Record was created without the necessary information,
+// or if the location is unavailable, it returns a non-nil *Source
+// with zero fields.
+func (r Record) source() *Source {
+ fs := runtime.CallersFrames([]uintptr{r.PC})
+ f, _ := fs.Next()
+ return &Source{
+ Function: f.Function,
+ File: f.File,
+ Line: f.Line,
+ }
+}
diff --git a/vendor/golang.org/x/exp/slog/text_handler.go b/vendor/golang.org/x/exp/slog/text_handler.go
new file mode 100644
index 000000000..75b66b716
--- /dev/null
+++ b/vendor/golang.org/x/exp/slog/text_handler.go
@@ -0,0 +1,161 @@
+// Copyright 2022 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.
+
+package slog
+
+import (
+ "context"
+ "encoding"
+ "fmt"
+ "io"
+ "reflect"
+ "strconv"
+ "unicode"
+ "unicode/utf8"
+)
+
+// TextHandler is a Handler that writes Records to an io.Writer as a
+// sequence of key=value pairs separated by spaces and followed by a newline.
+type TextHandler struct {
+ *commonHandler
+}
+
+// NewTextHandler creates a TextHandler that writes to w,
+// using the given options.
+// If opts is nil, the default options are used.
+func NewTextHandler(w io.Writer, opts *HandlerOptions) *TextHandler {
+ if opts == nil {
+ opts = &HandlerOptions{}
+ }
+ return &TextHandler{
+ &commonHandler{
+ json: false,
+ w: w,
+ opts: *opts,
+ },
+ }
+}
+
+// Enabled reports whether the handler handles records at the given level.
+// The handler ignores records whose level is lower.
+func (h *TextHandler) Enabled(_ context.Context, level Level) bool {
+ return h.commonHandler.enabled(level)
+}
+
+// WithAttrs returns a new TextHandler whose attributes consists
+// of h's attributes followed by attrs.
+func (h *TextHandler) WithAttrs(attrs []Attr) Handler {
+ return &TextHandler{commonHandler: h.commonHandler.withAttrs(attrs)}
+}
+
+func (h *TextHandler) WithGroup(name string) Handler {
+ return &TextHandler{commonHandler: h.commonHandler.withGroup(name)}
+}
+
+// Handle formats its argument Record as a single line of space-separated
+// key=value items.
+//
+// If the Record's time is zero, the time is omitted.
+// Otherwise, the key is "time"
+// and the value is output in RFC3339 format with millisecond precision.
+//
+// If the Record's level is zero, the level is omitted.
+// Otherwise, the key is "level"
+// and the value of [Level.String] is output.
+//
+// If the AddSource option is set and source information is available,
+// the key is "source" and the value is output as FILE:LINE.
+//
+// The message's key is "msg".
+//
+// To modify these or other attributes, or remove them from the output, use
+// [HandlerOptions.ReplaceAttr].
+//
+// If a value implements [encoding.TextMarshaler], the result of MarshalText is
+// written. Otherwise, the result of fmt.Sprint is written.
+//
+// Keys and values are quoted with [strconv.Quote] if they contain Unicode space
+// characters, non-printing characters, '"' or '='.
+//
+// Keys inside groups consist of components (keys or group names) separated by
+// dots. No further escaping is performed.
+// Thus there is no way to determine from the key "a.b.c" whether there
+// are two groups "a" and "b" and a key "c", or a single group "a.b" and a key "c",
+// or single group "a" and a key "b.c".
+// If it is necessary to reconstruct the group structure of a key
+// even in the presence of dots inside components, use
+// [HandlerOptions.ReplaceAttr] to encode that information in the key.
+//
+// Each call to Handle results in a single serialized call to
+// io.Writer.Write.
+func (h *TextHandler) Handle(_ context.Context, r Record) error {
+ return h.commonHandler.handle(r)
+}
+
+func appendTextValue(s *handleState, v Value) error {
+ switch v.Kind() {
+ case KindString:
+ s.appendString(v.str())
+ case KindTime:
+ s.appendTime(v.time())
+ case KindAny:
+ if tm, ok := v.any.(encoding.TextMarshaler); ok {
+ data, err := tm.MarshalText()
+ if err != nil {
+ return err
+ }
+ // TODO: avoid the conversion to string.
+ s.appendString(string(data))
+ return nil
+ }
+ if bs, ok := byteSlice(v.any); ok {
+ // As of Go 1.19, this only allocates for strings longer than 32 bytes.
+ s.buf.WriteString(strconv.Quote(string(bs)))
+ return nil
+ }
+ s.appendString(fmt.Sprintf("%+v", v.Any()))
+ default:
+ *s.buf = v.append(*s.buf)
+ }
+ return nil
+}
+
+// byteSlice returns its argument as a []byte if the argument's
+// underlying type is []byte, along with a second return value of true.
+// Otherwise it returns nil, false.
+func byteSlice(a any) ([]byte, bool) {
+ if bs, ok := a.([]byte); ok {
+ return bs, true
+ }
+ // Like Printf's %s, we allow both the slice type and the byte element type to be named.
+ t := reflect.TypeOf(a)
+ if t != nil && t.Kind() == reflect.Slice && t.Elem().Kind() == reflect.Uint8 {
+ return reflect.ValueOf(a).Bytes(), true
+ }
+ return nil, false
+}
+
+func needsQuoting(s string) bool {
+ if len(s) == 0 {
+ return true
+ }
+ for i := 0; i < len(s); {
+ b := s[i]
+ if b < utf8.RuneSelf {
+ // Quote anything except a backslash that would need quoting in a
+ // JSON string, as well as space and '='
+ if b != '\\' && (b == ' ' || b == '=' || !safeSet[b]) {
+ return true
+ }
+ i++
+ continue
+ }
+ r, size := utf8.DecodeRuneInString(s[i:])
+ if r == utf8.RuneError || unicode.IsSpace(r) || !unicode.IsPrint(r) {
+ return true
+ }
+ i += size
+ }
+ return false
+}
diff --git a/vendor/golang.org/x/exp/slog/value.go b/vendor/golang.org/x/exp/slog/value.go
new file mode 100644
index 000000000..3550c46fc
--- /dev/null
+++ b/vendor/golang.org/x/exp/slog/value.go
@@ -0,0 +1,456 @@
+// Copyright 2022 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.
+
+package slog
+
+import (
+ "fmt"
+ "math"
+ "runtime"
+ "strconv"
+ "strings"
+ "time"
+ "unsafe"
+
+ "golang.org/x/exp/slices"
+)
+
+// A Value can represent any Go value, but unlike type any,
+// it can represent most small values without an allocation.
+// The zero Value corresponds to nil.
+type Value struct {
+ _ [0]func() // disallow ==
+ // num holds the value for Kinds Int64, Uint64, Float64, Bool and Duration,
+ // the string length for KindString, and nanoseconds since the epoch for KindTime.
+ num uint64
+ // If any is of type Kind, then the value is in num as described above.
+ // If any is of type *time.Location, then the Kind is Time and time.Time value
+ // can be constructed from the Unix nanos in num and the location (monotonic time
+ // is not preserved).
+ // If any is of type stringptr, then the Kind is String and the string value
+ // consists of the length in num and the pointer in any.
+ // Otherwise, the Kind is Any and any is the value.
+ // (This implies that Attrs cannot store values of type Kind, *time.Location
+ // or stringptr.)
+ any any
+}
+
+// Kind is the kind of a Value.
+type Kind int
+
+// The following list is sorted alphabetically, but it's also important that
+// KindAny is 0 so that a zero Value represents nil.
+
+const (
+ KindAny Kind = iota
+ KindBool
+ KindDuration
+ KindFloat64
+ KindInt64
+ KindString
+ KindTime
+ KindUint64
+ KindGroup
+ KindLogValuer
+)
+
+var kindStrings = []string{
+ "Any",
+ "Bool",
+ "Duration",
+ "Float64",
+ "Int64",
+ "String",
+ "Time",
+ "Uint64",
+ "Group",
+ "LogValuer",
+}
+
+func (k Kind) String() string {
+ if k >= 0 && int(k) < len(kindStrings) {
+ return kindStrings[k]
+ }
+ return ""
+}
+
+// Unexported version of Kind, just so we can store Kinds in Values.
+// (No user-provided value has this type.)
+type kind Kind
+
+// Kind returns v's Kind.
+func (v Value) Kind() Kind {
+ switch x := v.any.(type) {
+ case Kind:
+ return x
+ case stringptr:
+ return KindString
+ case timeLocation:
+ return KindTime
+ case groupptr:
+ return KindGroup
+ case LogValuer:
+ return KindLogValuer
+ case kind: // a kind is just a wrapper for a Kind
+ return KindAny
+ default:
+ return KindAny
+ }
+}
+
+//////////////// Constructors
+
+// IntValue returns a Value for an int.
+func IntValue(v int) Value {
+ return Int64Value(int64(v))
+}
+
+// Int64Value returns a Value for an int64.
+func Int64Value(v int64) Value {
+ return Value{num: uint64(v), any: KindInt64}
+}
+
+// Uint64Value returns a Value for a uint64.
+func Uint64Value(v uint64) Value {
+ return Value{num: v, any: KindUint64}
+}
+
+// Float64Value returns a Value for a floating-point number.
+func Float64Value(v float64) Value {
+ return Value{num: math.Float64bits(v), any: KindFloat64}
+}
+
+// BoolValue returns a Value for a bool.
+func BoolValue(v bool) Value {
+ u := uint64(0)
+ if v {
+ u = 1
+ }
+ return Value{num: u, any: KindBool}
+}
+
+// Unexported version of *time.Location, just so we can store *time.Locations in
+// Values. (No user-provided value has this type.)
+type timeLocation *time.Location
+
+// TimeValue returns a Value for a time.Time.
+// It discards the monotonic portion.
+func TimeValue(v time.Time) Value {
+ if v.IsZero() {
+ // UnixNano on the zero time is undefined, so represent the zero time
+ // with a nil *time.Location instead. time.Time.Location method never
+ // returns nil, so a Value with any == timeLocation(nil) cannot be
+ // mistaken for any other Value, time.Time or otherwise.
+ return Value{any: timeLocation(nil)}
+ }
+ return Value{num: uint64(v.UnixNano()), any: timeLocation(v.Location())}
+}
+
+// DurationValue returns a Value for a time.Duration.
+func DurationValue(v time.Duration) Value {
+ return Value{num: uint64(v.Nanoseconds()), any: KindDuration}
+}
+
+// AnyValue returns a Value for the supplied value.
+//
+// If the supplied value is of type Value, it is returned
+// unmodified.
+//
+// Given a value of one of Go's predeclared string, bool, or
+// (non-complex) numeric types, AnyValue returns a Value of kind
+// String, Bool, Uint64, Int64, or Float64. The width of the
+// original numeric type is not preserved.
+//
+// Given a time.Time or time.Duration value, AnyValue returns a Value of kind
+// KindTime or KindDuration. The monotonic time is not preserved.
+//
+// For nil, or values of all other types, including named types whose
+// underlying type is numeric, AnyValue returns a value of kind KindAny.
+func AnyValue(v any) Value {
+ switch v := v.(type) {
+ case string:
+ return StringValue(v)
+ case int:
+ return Int64Value(int64(v))
+ case uint:
+ return Uint64Value(uint64(v))
+ case int64:
+ return Int64Value(v)
+ case uint64:
+ return Uint64Value(v)
+ case bool:
+ return BoolValue(v)
+ case time.Duration:
+ return DurationValue(v)
+ case time.Time:
+ return TimeValue(v)
+ case uint8:
+ return Uint64Value(uint64(v))
+ case uint16:
+ return Uint64Value(uint64(v))
+ case uint32:
+ return Uint64Value(uint64(v))
+ case uintptr:
+ return Uint64Value(uint64(v))
+ case int8:
+ return Int64Value(int64(v))
+ case int16:
+ return Int64Value(int64(v))
+ case int32:
+ return Int64Value(int64(v))
+ case float64:
+ return Float64Value(v)
+ case float32:
+ return Float64Value(float64(v))
+ case []Attr:
+ return GroupValue(v...)
+ case Kind:
+ return Value{any: kind(v)}
+ case Value:
+ return v
+ default:
+ return Value{any: v}
+ }
+}
+
+//////////////// Accessors
+
+// Any returns v's value as an any.
+func (v Value) Any() any {
+ switch v.Kind() {
+ case KindAny:
+ if k, ok := v.any.(kind); ok {
+ return Kind(k)
+ }
+ return v.any
+ case KindLogValuer:
+ return v.any
+ case KindGroup:
+ return v.group()
+ case KindInt64:
+ return int64(v.num)
+ case KindUint64:
+ return v.num
+ case KindFloat64:
+ return v.float()
+ case KindString:
+ return v.str()
+ case KindBool:
+ return v.bool()
+ case KindDuration:
+ return v.duration()
+ case KindTime:
+ return v.time()
+ default:
+ panic(fmt.Sprintf("bad kind: %s", v.Kind()))
+ }
+}
+
+// Int64 returns v's value as an int64. It panics
+// if v is not a signed integer.
+func (v Value) Int64() int64 {
+ if g, w := v.Kind(), KindInt64; g != w {
+ panic(fmt.Sprintf("Value kind is %s, not %s", g, w))
+ }
+ return int64(v.num)
+}
+
+// Uint64 returns v's value as a uint64. It panics
+// if v is not an unsigned integer.
+func (v Value) Uint64() uint64 {
+ if g, w := v.Kind(), KindUint64; g != w {
+ panic(fmt.Sprintf("Value kind is %s, not %s", g, w))
+ }
+ return v.num
+}
+
+// Bool returns v's value as a bool. It panics
+// if v is not a bool.
+func (v Value) Bool() bool {
+ if g, w := v.Kind(), KindBool; g != w {
+ panic(fmt.Sprintf("Value kind is %s, not %s", g, w))
+ }
+ return v.bool()
+}
+
+func (v Value) bool() bool {
+ return v.num == 1
+}
+
+// Duration returns v's value as a time.Duration. It panics
+// if v is not a time.Duration.
+func (v Value) Duration() time.Duration {
+ if g, w := v.Kind(), KindDuration; g != w {
+ panic(fmt.Sprintf("Value kind is %s, not %s", g, w))
+ }
+
+ return v.duration()
+}
+
+func (v Value) duration() time.Duration {
+ return time.Duration(int64(v.num))
+}
+
+// Float64 returns v's value as a float64. It panics
+// if v is not a float64.
+func (v Value) Float64() float64 {
+ if g, w := v.Kind(), KindFloat64; g != w {
+ panic(fmt.Sprintf("Value kind is %s, not %s", g, w))
+ }
+
+ return v.float()
+}
+
+func (v Value) float() float64 {
+ return math.Float64frombits(v.num)
+}
+
+// Time returns v's value as a time.Time. It panics
+// if v is not a time.Time.
+func (v Value) Time() time.Time {
+ if g, w := v.Kind(), KindTime; g != w {
+ panic(fmt.Sprintf("Value kind is %s, not %s", g, w))
+ }
+ return v.time()
+}
+
+func (v Value) time() time.Time {
+ loc := v.any.(timeLocation)
+ if loc == nil {
+ return time.Time{}
+ }
+ return time.Unix(0, int64(v.num)).In(loc)
+}
+
+// LogValuer returns v's value as a LogValuer. It panics
+// if v is not a LogValuer.
+func (v Value) LogValuer() LogValuer {
+ return v.any.(LogValuer)
+}
+
+// Group returns v's value as a []Attr.
+// It panics if v's Kind is not KindGroup.
+func (v Value) Group() []Attr {
+ if sp, ok := v.any.(groupptr); ok {
+ return unsafe.Slice((*Attr)(sp), v.num)
+ }
+ panic("Group: bad kind")
+}
+
+func (v Value) group() []Attr {
+ return unsafe.Slice((*Attr)(v.any.(groupptr)), v.num)
+}
+
+//////////////// Other
+
+// Equal reports whether v and w represent the same Go value.
+func (v Value) Equal(w Value) bool {
+ k1 := v.Kind()
+ k2 := w.Kind()
+ if k1 != k2 {
+ return false
+ }
+ switch k1 {
+ case KindInt64, KindUint64, KindBool, KindDuration:
+ return v.num == w.num
+ case KindString:
+ return v.str() == w.str()
+ case KindFloat64:
+ return v.float() == w.float()
+ case KindTime:
+ return v.time().Equal(w.time())
+ case KindAny, KindLogValuer:
+ return v.any == w.any // may panic if non-comparable
+ case KindGroup:
+ return slices.EqualFunc(v.group(), w.group(), Attr.Equal)
+ default:
+ panic(fmt.Sprintf("bad kind: %s", k1))
+ }
+}
+
+// append appends a text representation of v to dst.
+// v is formatted as with fmt.Sprint.
+func (v Value) append(dst []byte) []byte {
+ switch v.Kind() {
+ case KindString:
+ return append(dst, v.str()...)
+ case KindInt64:
+ return strconv.AppendInt(dst, int64(v.num), 10)
+ case KindUint64:
+ return strconv.AppendUint(dst, v.num, 10)
+ case KindFloat64:
+ return strconv.AppendFloat(dst, v.float(), 'g', -1, 64)
+ case KindBool:
+ return strconv.AppendBool(dst, v.bool())
+ case KindDuration:
+ return append(dst, v.duration().String()...)
+ case KindTime:
+ return append(dst, v.time().String()...)
+ case KindGroup:
+ return fmt.Append(dst, v.group())
+ case KindAny, KindLogValuer:
+ return fmt.Append(dst, v.any)
+ default:
+ panic(fmt.Sprintf("bad kind: %s", v.Kind()))
+ }
+}
+
+// A LogValuer is any Go value that can convert itself into a Value for logging.
+//
+// This mechanism may be used to defer expensive operations until they are
+// needed, or to expand a single value into a sequence of components.
+type LogValuer interface {
+ LogValue() Value
+}
+
+const maxLogValues = 100
+
+// Resolve repeatedly calls LogValue on v while it implements LogValuer,
+// and returns the result.
+// If v resolves to a group, the group's attributes' values are not recursively
+// resolved.
+// If the number of LogValue calls exceeds a threshold, a Value containing an
+// error is returned.
+// Resolve's return value is guaranteed not to be of Kind KindLogValuer.
+func (v Value) Resolve() (rv Value) {
+ orig := v
+ defer func() {
+ if r := recover(); r != nil {
+ rv = AnyValue(fmt.Errorf("LogValue panicked\n%s", stack(3, 5)))
+ }
+ }()
+
+ for i := 0; i < maxLogValues; i++ {
+ if v.Kind() != KindLogValuer {
+ return v
+ }
+ v = v.LogValuer().LogValue()
+ }
+ err := fmt.Errorf("LogValue called too many times on Value of type %T", orig.Any())
+ return AnyValue(err)
+}
+
+func stack(skip, nFrames int) string {
+ pcs := make([]uintptr, nFrames+1)
+ n := runtime.Callers(skip+1, pcs)
+ if n == 0 {
+ return "(no stack)"
+ }
+ frames := runtime.CallersFrames(pcs[:n])
+ var b strings.Builder
+ i := 0
+ for {
+ frame, more := frames.Next()
+ fmt.Fprintf(&b, "called from %s (%s:%d)\n", frame.Function, frame.File, frame.Line)
+ if !more {
+ break
+ }
+ i++
+ if i >= nFrames {
+ fmt.Fprintf(&b, "(rest of stack elided)\n")
+ break
+ }
+ }
+ return b.String()
+}
diff --git a/vendor/golang.org/x/exp/slog/value_119.go b/vendor/golang.org/x/exp/slog/value_119.go
new file mode 100644
index 000000000..29b0d7329
--- /dev/null
+++ b/vendor/golang.org/x/exp/slog/value_119.go
@@ -0,0 +1,53 @@
+// Copyright 2022 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 go1.19 && !go1.20
+
+package slog
+
+import (
+ "reflect"
+ "unsafe"
+)
+
+type (
+ stringptr unsafe.Pointer // used in Value.any when the Value is a string
+ groupptr unsafe.Pointer // used in Value.any when the Value is a []Attr
+)
+
+// StringValue returns a new Value for a string.
+func StringValue(value string) Value {
+ hdr := (*reflect.StringHeader)(unsafe.Pointer(&value))
+ return Value{num: uint64(hdr.Len), any: stringptr(hdr.Data)}
+}
+
+func (v Value) str() string {
+ var s string
+ hdr := (*reflect.StringHeader)(unsafe.Pointer(&s))
+ hdr.Data = uintptr(v.any.(stringptr))
+ hdr.Len = int(v.num)
+ return s
+}
+
+// String returns Value's value as a string, formatted like fmt.Sprint. Unlike
+// the methods Int64, Float64, and so on, which panic if v is of the
+// wrong kind, String never panics.
+func (v Value) String() string {
+ if sp, ok := v.any.(stringptr); ok {
+ // Inlining this code makes a huge difference.
+ var s string
+ hdr := (*reflect.StringHeader)(unsafe.Pointer(&s))
+ hdr.Data = uintptr(sp)
+ hdr.Len = int(v.num)
+ return s
+ }
+ return string(v.append(nil))
+}
+
+// GroupValue returns a new Value for a list of Attrs.
+// The caller must not subsequently mutate the argument slice.
+func GroupValue(as ...Attr) Value {
+ hdr := (*reflect.SliceHeader)(unsafe.Pointer(&as))
+ return Value{num: uint64(hdr.Len), any: groupptr(hdr.Data)}
+}
diff --git a/vendor/golang.org/x/exp/slog/value_120.go b/vendor/golang.org/x/exp/slog/value_120.go
new file mode 100644
index 000000000..f7d4c0932
--- /dev/null
+++ b/vendor/golang.org/x/exp/slog/value_120.go
@@ -0,0 +1,39 @@
+// Copyright 2022 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 go1.20
+
+package slog
+
+import "unsafe"
+
+type (
+ stringptr *byte // used in Value.any when the Value is a string
+ groupptr *Attr // used in Value.any when the Value is a []Attr
+)
+
+// StringValue returns a new Value for a string.
+func StringValue(value string) Value {
+ return Value{num: uint64(len(value)), any: stringptr(unsafe.StringData(value))}
+}
+
+// GroupValue returns a new Value for a list of Attrs.
+// The caller must not subsequently mutate the argument slice.
+func GroupValue(as ...Attr) Value {
+ return Value{num: uint64(len(as)), any: groupptr(unsafe.SliceData(as))}
+}
+
+// String returns Value's value as a string, formatted like fmt.Sprint. Unlike
+// the methods Int64, Float64, and so on, which panic if v is of the
+// wrong kind, String never panics.
+func (v Value) String() string {
+ if sp, ok := v.any.(stringptr); ok {
+ return unsafe.String(sp, v.num)
+ }
+ return string(v.append(nil))
+}
+
+func (v Value) str() string {
+ return unsafe.String(v.any.(stringptr), v.num)
+}
diff --git a/vendor/golang.org/x/sys/execabs/execabs.go b/vendor/golang.org/x/sys/execabs/execabs.go
deleted file mode 100644
index 3bf40fdfe..000000000
--- a/vendor/golang.org/x/sys/execabs/execabs.go
+++ /dev/null
@@ -1,102 +0,0 @@
-// 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.
-
-// Package execabs is a drop-in replacement for os/exec
-// that requires PATH lookups to find absolute paths.
-// That is, execabs.Command("cmd") runs the same PATH lookup
-// as exec.Command("cmd"), but if the result is a path
-// which is relative, the Run and Start methods will report
-// an error instead of running the executable.
-//
-// See https://blog.golang.org/path-security for more information
-// about when it may be necessary or appropriate to use this package.
-package execabs
-
-import (
- "context"
- "fmt"
- "os/exec"
- "path/filepath"
- "reflect"
- "unsafe"
-)
-
-// ErrNotFound is the error resulting if a path search failed to find an executable file.
-// It is an alias for exec.ErrNotFound.
-var ErrNotFound = exec.ErrNotFound
-
-// Cmd represents an external command being prepared or run.
-// It is an alias for exec.Cmd.
-type Cmd = exec.Cmd
-
-// Error is returned by LookPath when it fails to classify a file as an executable.
-// It is an alias for exec.Error.
-type Error = exec.Error
-
-// An ExitError reports an unsuccessful exit by a command.
-// It is an alias for exec.ExitError.
-type ExitError = exec.ExitError
-
-func relError(file, path string) error {
- return fmt.Errorf("%s resolves to executable in current directory (.%c%s)", file, filepath.Separator, path)
-}
-
-// LookPath searches for an executable named file in the directories
-// named by the PATH environment variable. If file contains a slash,
-// it is tried directly and the PATH is not consulted. The result will be
-// an absolute path.
-//
-// LookPath differs from exec.LookPath in its handling of PATH lookups,
-// which are used for file names without slashes. If exec.LookPath's
-// PATH lookup would have returned an executable from the current directory,
-// LookPath instead returns an error.
-func LookPath(file string) (string, error) {
- path, err := exec.LookPath(file)
- if err != nil && !isGo119ErrDot(err) {
- return "", err
- }
- if filepath.Base(file) == file && !filepath.IsAbs(path) {
- return "", relError(file, path)
- }
- return path, nil
-}
-
-func fixCmd(name string, cmd *exec.Cmd) {
- if filepath.Base(name) == name && !filepath.IsAbs(cmd.Path) && !isGo119ErrFieldSet(cmd) {
- // exec.Command was called with a bare binary name and
- // exec.LookPath returned a path which is not absolute.
- // Set cmd.lookPathErr and clear cmd.Path so that it
- // cannot be run.
- lookPathErr := (*error)(unsafe.Pointer(reflect.ValueOf(cmd).Elem().FieldByName("lookPathErr").Addr().Pointer()))
- if *lookPathErr == nil {
- *lookPathErr = relError(name, cmd.Path)
- }
- cmd.Path = ""
- }
-}
-
-// CommandContext is like Command but includes a context.
-//
-// The provided context is used to kill the process (by calling os.Process.Kill)
-// if the context becomes done before the command completes on its own.
-func CommandContext(ctx context.Context, name string, arg ...string) *exec.Cmd {
- cmd := exec.CommandContext(ctx, name, arg...)
- fixCmd(name, cmd)
- return cmd
-
-}
-
-// Command returns the Cmd struct to execute the named program with the given arguments.
-// See exec.Command for most details.
-//
-// Command differs from exec.Command in its handling of PATH lookups,
-// which are used when the program name contains no slashes.
-// If exec.Command would have returned an exec.Cmd configured to run an
-// executable from the current directory, Command instead
-// returns an exec.Cmd that will return an error from Start or Run.
-func Command(name string, arg ...string) *exec.Cmd {
- cmd := exec.Command(name, arg...)
- fixCmd(name, cmd)
- return cmd
-}
diff --git a/vendor/golang.org/x/sys/execabs/execabs_go118.go b/vendor/golang.org/x/sys/execabs/execabs_go118.go
deleted file mode 100644
index 5627d70e3..000000000
--- a/vendor/golang.org/x/sys/execabs/execabs_go118.go
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2022 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 !go1.19
-
-package execabs
-
-import "os/exec"
-
-func isGo119ErrDot(err error) bool {
- return false
-}
-
-func isGo119ErrFieldSet(cmd *exec.Cmd) bool {
- return false
-}
diff --git a/vendor/golang.org/x/sys/execabs/execabs_go119.go b/vendor/golang.org/x/sys/execabs/execabs_go119.go
deleted file mode 100644
index d60ab1b41..000000000
--- a/vendor/golang.org/x/sys/execabs/execabs_go119.go
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright 2022 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 go1.19
-
-package execabs
-
-import (
- "errors"
- "os/exec"
-)
-
-func isGo119ErrDot(err error) bool {
- return errors.Is(err, exec.ErrDot)
-}
-
-func isGo119ErrFieldSet(cmd *exec.Cmd) bool {
- return cmd.Err != nil
-}
diff --git a/vendor/golang.org/x/text/encoding/encoding.go b/vendor/golang.org/x/text/encoding/encoding.go
new file mode 100644
index 000000000..a0bd7cd4d
--- /dev/null
+++ b/vendor/golang.org/x/text/encoding/encoding.go
@@ -0,0 +1,335 @@
+// Copyright 2013 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.
+
+// Package encoding defines an interface for character encodings, such as Shift
+// JIS and Windows 1252, that can convert to and from UTF-8.
+//
+// Encoding implementations are provided in other packages, such as
+// golang.org/x/text/encoding/charmap and
+// golang.org/x/text/encoding/japanese.
+package encoding // import "golang.org/x/text/encoding"
+
+import (
+ "errors"
+ "io"
+ "strconv"
+ "unicode/utf8"
+
+ "golang.org/x/text/encoding/internal/identifier"
+ "golang.org/x/text/transform"
+)
+
+// TODO:
+// - There seems to be some inconsistency in when decoders return errors
+// and when not. Also documentation seems to suggest they shouldn't return
+// errors at all (except for UTF-16).
+// - Encoders seem to rely on or at least benefit from the input being in NFC
+// normal form. Perhaps add an example how users could prepare their output.
+
+// Encoding is a character set encoding that can be transformed to and from
+// UTF-8.
+type Encoding interface {
+ // NewDecoder returns a Decoder.
+ NewDecoder() *Decoder
+
+ // NewEncoder returns an Encoder.
+ NewEncoder() *Encoder
+}
+
+// A Decoder converts bytes to UTF-8. It implements transform.Transformer.
+//
+// Transforming source bytes that are not of that encoding will not result in an
+// error per se. Each byte that cannot be transcoded will be represented in the
+// output by the UTF-8 encoding of '\uFFFD', the replacement rune.
+type Decoder struct {
+ transform.Transformer
+
+ // This forces external creators of Decoders to use names in struct
+ // initializers, allowing for future extendibility without having to break
+ // code.
+ _ struct{}
+}
+
+// Bytes converts the given encoded bytes to UTF-8. It returns the converted
+// bytes or nil, err if any error occurred.
+func (d *Decoder) Bytes(b []byte) ([]byte, error) {
+ b, _, err := transform.Bytes(d, b)
+ if err != nil {
+ return nil, err
+ }
+ return b, nil
+}
+
+// String converts the given encoded string to UTF-8. It returns the converted
+// string or "", err if any error occurred.
+func (d *Decoder) String(s string) (string, error) {
+ s, _, err := transform.String(d, s)
+ if err != nil {
+ return "", err
+ }
+ return s, nil
+}
+
+// Reader wraps another Reader to decode its bytes.
+//
+// The Decoder may not be used for any other operation as long as the returned
+// Reader is in use.
+func (d *Decoder) Reader(r io.Reader) io.Reader {
+ return transform.NewReader(r, d)
+}
+
+// An Encoder converts bytes from UTF-8. It implements transform.Transformer.
+//
+// Each rune that cannot be transcoded will result in an error. In this case,
+// the transform will consume all source byte up to, not including the offending
+// rune. Transforming source bytes that are not valid UTF-8 will be replaced by
+// `\uFFFD`. To return early with an error instead, use transform.Chain to
+// preprocess the data with a UTF8Validator.
+type Encoder struct {
+ transform.Transformer
+
+ // This forces external creators of Encoders to use names in struct
+ // initializers, allowing for future extendibility without having to break
+ // code.
+ _ struct{}
+}
+
+// Bytes converts bytes from UTF-8. It returns the converted bytes or nil, err if
+// any error occurred.
+func (e *Encoder) Bytes(b []byte) ([]byte, error) {
+ b, _, err := transform.Bytes(e, b)
+ if err != nil {
+ return nil, err
+ }
+ return b, nil
+}
+
+// String converts a string from UTF-8. It returns the converted string or
+// "", err if any error occurred.
+func (e *Encoder) String(s string) (string, error) {
+ s, _, err := transform.String(e, s)
+ if err != nil {
+ return "", err
+ }
+ return s, nil
+}
+
+// Writer wraps another Writer to encode its UTF-8 output.
+//
+// The Encoder may not be used for any other operation as long as the returned
+// Writer is in use.
+func (e *Encoder) Writer(w io.Writer) io.Writer {
+ return transform.NewWriter(w, e)
+}
+
+// ASCIISub is the ASCII substitute character, as recommended by
+// https://unicode.org/reports/tr36/#Text_Comparison
+const ASCIISub = '\x1a'
+
+// Nop is the nop encoding. Its transformed bytes are the same as the source
+// bytes; it does not replace invalid UTF-8 sequences.
+var Nop Encoding = nop{}
+
+type nop struct{}
+
+func (nop) NewDecoder() *Decoder {
+ return &Decoder{Transformer: transform.Nop}
+}
+func (nop) NewEncoder() *Encoder {
+ return &Encoder{Transformer: transform.Nop}
+}
+
+// Replacement is the replacement encoding. Decoding from the replacement
+// encoding yields a single '\uFFFD' replacement rune. Encoding from UTF-8 to
+// the replacement encoding yields the same as the source bytes except that
+// invalid UTF-8 is converted to '\uFFFD'.
+//
+// It is defined at http://encoding.spec.whatwg.org/#replacement
+var Replacement Encoding = replacement{}
+
+type replacement struct{}
+
+func (replacement) NewDecoder() *Decoder {
+ return &Decoder{Transformer: replacementDecoder{}}
+}
+
+func (replacement) NewEncoder() *Encoder {
+ return &Encoder{Transformer: replacementEncoder{}}
+}
+
+func (replacement) ID() (mib identifier.MIB, other string) {
+ return identifier.Replacement, ""
+}
+
+type replacementDecoder struct{ transform.NopResetter }
+
+func (replacementDecoder) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) {
+ if len(dst) < 3 {
+ return 0, 0, transform.ErrShortDst
+ }
+ if atEOF {
+ const fffd = "\ufffd"
+ dst[0] = fffd[0]
+ dst[1] = fffd[1]
+ dst[2] = fffd[2]
+ nDst = 3
+ }
+ return nDst, len(src), nil
+}
+
+type replacementEncoder struct{ transform.NopResetter }
+
+func (replacementEncoder) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) {
+ r, size := rune(0), 0
+
+ for ; nSrc < len(src); nSrc += size {
+ r = rune(src[nSrc])
+
+ // Decode a 1-byte rune.
+ if r < utf8.RuneSelf {
+ size = 1
+
+ } else {
+ // Decode a multi-byte rune.
+ r, size = utf8.DecodeRune(src[nSrc:])
+ if size == 1 {
+ // All valid runes of size 1 (those below utf8.RuneSelf) were
+ // handled above. We have invalid UTF-8 or we haven't seen the
+ // full character yet.
+ if !atEOF && !utf8.FullRune(src[nSrc:]) {
+ err = transform.ErrShortSrc
+ break
+ }
+ r = '\ufffd'
+ }
+ }
+
+ if nDst+utf8.RuneLen(r) > len(dst) {
+ err = transform.ErrShortDst
+ break
+ }
+ nDst += utf8.EncodeRune(dst[nDst:], r)
+ }
+ return nDst, nSrc, err
+}
+
+// HTMLEscapeUnsupported wraps encoders to replace source runes outside the
+// repertoire of the destination encoding with HTML escape sequences.
+//
+// This wrapper exists to comply to URL and HTML forms requiring a
+// non-terminating legacy encoder. The produced sequences may lead to data
+// loss as they are indistinguishable from legitimate input. To avoid this
+// issue, use UTF-8 encodings whenever possible.
+func HTMLEscapeUnsupported(e *Encoder) *Encoder {
+ return &Encoder{Transformer: &errorHandler{e, errorToHTML}}
+}
+
+// ReplaceUnsupported wraps encoders to replace source runes outside the
+// repertoire of the destination encoding with an encoding-specific
+// replacement.
+//
+// This wrapper is only provided for backwards compatibility and legacy
+// handling. Its use is strongly discouraged. Use UTF-8 whenever possible.
+func ReplaceUnsupported(e *Encoder) *Encoder {
+ return &Encoder{Transformer: &errorHandler{e, errorToReplacement}}
+}
+
+type errorHandler struct {
+ *Encoder
+ handler func(dst []byte, r rune, err repertoireError) (n int, ok bool)
+}
+
+// TODO: consider making this error public in some form.
+type repertoireError interface {
+ Replacement() byte
+}
+
+func (h errorHandler) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) {
+ nDst, nSrc, err = h.Transformer.Transform(dst, src, atEOF)
+ for err != nil {
+ rerr, ok := err.(repertoireError)
+ if !ok {
+ return nDst, nSrc, err
+ }
+ r, sz := utf8.DecodeRune(src[nSrc:])
+ n, ok := h.handler(dst[nDst:], r, rerr)
+ if !ok {
+ return nDst, nSrc, transform.ErrShortDst
+ }
+ err = nil
+ nDst += n
+ if nSrc += sz; nSrc < len(src) {
+ var dn, sn int
+ dn, sn, err = h.Transformer.Transform(dst[nDst:], src[nSrc:], atEOF)
+ nDst += dn
+ nSrc += sn
+ }
+ }
+ return nDst, nSrc, err
+}
+
+func errorToHTML(dst []byte, r rune, err repertoireError) (n int, ok bool) {
+ buf := [8]byte{}
+ b := strconv.AppendUint(buf[:0], uint64(r), 10)
+ if n = len(b) + len(""); n >= len(dst) {
+ return 0, false
+ }
+ dst[0] = '&'
+ dst[1] = '#'
+ dst[copy(dst[2:], b)+2] = ';'
+ return n, true
+}
+
+func errorToReplacement(dst []byte, r rune, err repertoireError) (n int, ok bool) {
+ if len(dst) == 0 {
+ return 0, false
+ }
+ dst[0] = err.Replacement()
+ return 1, true
+}
+
+// ErrInvalidUTF8 means that a transformer encountered invalid UTF-8.
+var ErrInvalidUTF8 = errors.New("encoding: invalid UTF-8")
+
+// UTF8Validator is a transformer that returns ErrInvalidUTF8 on the first
+// input byte that is not valid UTF-8.
+var UTF8Validator transform.Transformer = utf8Validator{}
+
+type utf8Validator struct{ transform.NopResetter }
+
+func (utf8Validator) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) {
+ n := len(src)
+ if n > len(dst) {
+ n = len(dst)
+ }
+ for i := 0; i < n; {
+ if c := src[i]; c < utf8.RuneSelf {
+ dst[i] = c
+ i++
+ continue
+ }
+ _, size := utf8.DecodeRune(src[i:])
+ if size == 1 {
+ // All valid runes of size 1 (those below utf8.RuneSelf) were
+ // handled above. We have invalid UTF-8 or we haven't seen the
+ // full character yet.
+ err = ErrInvalidUTF8
+ if !atEOF && !utf8.FullRune(src[i:]) {
+ err = transform.ErrShortSrc
+ }
+ return i, i, err
+ }
+ if i+size > len(dst) {
+ return i, i, transform.ErrShortDst
+ }
+ for ; size > 0; size-- {
+ dst[i] = src[i]
+ i++
+ }
+ }
+ if len(src) > len(dst) {
+ err = transform.ErrShortDst
+ }
+ return n, n, err
+}
diff --git a/vendor/golang.org/x/text/encoding/internal/identifier/identifier.go b/vendor/golang.org/x/text/encoding/internal/identifier/identifier.go
new file mode 100644
index 000000000..5c9b85c28
--- /dev/null
+++ b/vendor/golang.org/x/text/encoding/internal/identifier/identifier.go
@@ -0,0 +1,81 @@
+// Copyright 2015 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:generate go run gen.go
+
+// Package identifier defines the contract between implementations of Encoding
+// and Index by defining identifiers that uniquely identify standardized coded
+// character sets (CCS) and character encoding schemes (CES), which we will
+// together refer to as encodings, for which Encoding implementations provide
+// converters to and from UTF-8. This package is typically only of concern to
+// implementers of Indexes and Encodings.
+//
+// One part of the identifier is the MIB code, which is defined by IANA and
+// uniquely identifies a CCS or CES. Each code is associated with data that
+// references authorities, official documentation as well as aliases and MIME
+// names.
+//
+// Not all CESs are covered by the IANA registry. The "other" string that is
+// returned by ID can be used to identify other character sets or versions of
+// existing ones.
+//
+// It is recommended that each package that provides a set of Encodings provide
+// the All and Common variables to reference all supported encodings and
+// commonly used subset. This allows Index implementations to include all
+// available encodings without explicitly referencing or knowing about them.
+package identifier
+
+// Note: this package is internal, but could be made public if there is a need
+// for writing third-party Indexes and Encodings.
+
+// References:
+// - http://source.icu-project.org/repos/icu/icu/trunk/source/data/mappings/convrtrs.txt
+// - http://www.iana.org/assignments/character-sets/character-sets.xhtml
+// - http://www.iana.org/assignments/ianacharset-mib/ianacharset-mib
+// - http://www.ietf.org/rfc/rfc2978.txt
+// - https://www.unicode.org/reports/tr22/
+// - http://www.w3.org/TR/encoding/
+// - https://encoding.spec.whatwg.org/
+// - https://encoding.spec.whatwg.org/encodings.json
+// - https://tools.ietf.org/html/rfc6657#section-5
+
+// Interface can be implemented by Encodings to define the CCS or CES for which
+// it implements conversions.
+type Interface interface {
+ // ID returns an encoding identifier. Exactly one of the mib and other
+ // values should be non-zero.
+ //
+ // In the usual case it is only necessary to indicate the MIB code. The
+ // other string can be used to specify encodings for which there is no MIB,
+ // such as "x-mac-dingbat".
+ //
+ // The other string may only contain the characters a-z, A-Z, 0-9, - and _.
+ ID() (mib MIB, other string)
+
+ // NOTE: the restrictions on the encoding are to allow extending the syntax
+ // with additional information such as versions, vendors and other variants.
+}
+
+// A MIB identifies an encoding. It is derived from the IANA MIB codes and adds
+// some identifiers for some encodings that are not covered by the IANA
+// standard.
+//
+// See http://www.iana.org/assignments/ianacharset-mib.
+type MIB uint16
+
+// These additional MIB types are not defined in IANA. They are added because
+// they are common and defined within the text repo.
+const (
+ // Unofficial marks the start of encodings not registered by IANA.
+ Unofficial MIB = 10000 + iota
+
+ // Replacement is the WhatWG replacement encoding.
+ Replacement
+
+ // XUserDefined is the code for x-user-defined.
+ XUserDefined
+
+ // MacintoshCyrillic is the code for x-mac-cyrillic.
+ MacintoshCyrillic
+)
diff --git a/vendor/golang.org/x/text/encoding/internal/identifier/mib.go b/vendor/golang.org/x/text/encoding/internal/identifier/mib.go
new file mode 100644
index 000000000..351fb86e2
--- /dev/null
+++ b/vendor/golang.org/x/text/encoding/internal/identifier/mib.go
@@ -0,0 +1,1627 @@
+// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
+
+package identifier
+
+const (
+ // ASCII is the MIB identifier with IANA name US-ASCII (MIME: US-ASCII).
+ //
+ // ANSI X3.4-1986
+ // Reference: RFC2046
+ ASCII MIB = 3
+
+ // ISOLatin1 is the MIB identifier with IANA name ISO_8859-1:1987 (MIME: ISO-8859-1).
+ //
+ // ISO-IR: International Register of Escape Sequences
+ // Note: The current registration authority is IPSJ/ITSCJ, Japan.
+ // Reference: RFC1345
+ ISOLatin1 MIB = 4
+
+ // ISOLatin2 is the MIB identifier with IANA name ISO_8859-2:1987 (MIME: ISO-8859-2).
+ //
+ // ISO-IR: International Register of Escape Sequences
+ // Note: The current registration authority is IPSJ/ITSCJ, Japan.
+ // Reference: RFC1345
+ ISOLatin2 MIB = 5
+
+ // ISOLatin3 is the MIB identifier with IANA name ISO_8859-3:1988 (MIME: ISO-8859-3).
+ //
+ // ISO-IR: International Register of Escape Sequences
+ // Note: The current registration authority is IPSJ/ITSCJ, Japan.
+ // Reference: RFC1345
+ ISOLatin3 MIB = 6
+
+ // ISOLatin4 is the MIB identifier with IANA name ISO_8859-4:1988 (MIME: ISO-8859-4).
+ //
+ // ISO-IR: International Register of Escape Sequences
+ // Note: The current registration authority is IPSJ/ITSCJ, Japan.
+ // Reference: RFC1345
+ ISOLatin4 MIB = 7
+
+ // ISOLatinCyrillic is the MIB identifier with IANA name ISO_8859-5:1988 (MIME: ISO-8859-5).
+ //
+ // ISO-IR: International Register of Escape Sequences
+ // Note: The current registration authority is IPSJ/ITSCJ, Japan.
+ // Reference: RFC1345
+ ISOLatinCyrillic MIB = 8
+
+ // ISOLatinArabic is the MIB identifier with IANA name ISO_8859-6:1987 (MIME: ISO-8859-6).
+ //
+ // ISO-IR: International Register of Escape Sequences
+ // Note: The current registration authority is IPSJ/ITSCJ, Japan.
+ // Reference: RFC1345
+ ISOLatinArabic MIB = 9
+
+ // ISOLatinGreek is the MIB identifier with IANA name ISO_8859-7:1987 (MIME: ISO-8859-7).
+ //
+ // ISO-IR: International Register of Escape Sequences
+ // Note: The current registration authority is IPSJ/ITSCJ, Japan.
+ // Reference: RFC1947
+ // Reference: RFC1345
+ ISOLatinGreek MIB = 10
+
+ // ISOLatinHebrew is the MIB identifier with IANA name ISO_8859-8:1988 (MIME: ISO-8859-8).
+ //
+ // ISO-IR: International Register of Escape Sequences
+ // Note: The current registration authority is IPSJ/ITSCJ, Japan.
+ // Reference: RFC1345
+ ISOLatinHebrew MIB = 11
+
+ // ISOLatin5 is the MIB identifier with IANA name ISO_8859-9:1989 (MIME: ISO-8859-9).
+ //
+ // ISO-IR: International Register of Escape Sequences
+ // Note: The current registration authority is IPSJ/ITSCJ, Japan.
+ // Reference: RFC1345
+ ISOLatin5 MIB = 12
+
+ // ISOLatin6 is the MIB identifier with IANA name ISO-8859-10 (MIME: ISO-8859-10).
+ //
+ // ISO-IR: International Register of Escape Sequences
+ // Note: The current registration authority is IPSJ/ITSCJ, Japan.
+ // Reference: RFC1345
+ ISOLatin6 MIB = 13
+
+ // ISOTextComm is the MIB identifier with IANA name ISO_6937-2-add.
+ //
+ // ISO-IR: International Register of Escape Sequences and ISO 6937-2:1983
+ // Note: The current registration authority is IPSJ/ITSCJ, Japan.
+ // Reference: RFC1345
+ ISOTextComm MIB = 14
+
+ // HalfWidthKatakana is the MIB identifier with IANA name JIS_X0201.
+ //
+ // JIS X 0201-1976. One byte only, this is equivalent to
+ // JIS/Roman (similar to ASCII) plus eight-bit half-width
+ // Katakana
+ // Reference: RFC1345
+ HalfWidthKatakana MIB = 15
+
+ // JISEncoding is the MIB identifier with IANA name JIS_Encoding.
+ //
+ // JIS X 0202-1991. Uses ISO 2022 escape sequences to
+ // shift code sets as documented in JIS X 0202-1991.
+ JISEncoding MIB = 16
+
+ // ShiftJIS is the MIB identifier with IANA name Shift_JIS (MIME: Shift_JIS).
+ //
+ // This charset is an extension of csHalfWidthKatakana by
+ // adding graphic characters in JIS X 0208. The CCS's are
+ // JIS X0201:1997 and JIS X0208:1997. The
+ // complete definition is shown in Appendix 1 of JIS
+ // X0208:1997.
+ // This charset can be used for the top-level media type "text".
+ ShiftJIS MIB = 17
+
+ // EUCPkdFmtJapanese is the MIB identifier with IANA name Extended_UNIX_Code_Packed_Format_for_Japanese (MIME: EUC-JP).
+ //
+ // Standardized by OSF, UNIX International, and UNIX Systems
+ // Laboratories Pacific. Uses ISO 2022 rules to select
+ // code set 0: US-ASCII (a single 7-bit byte set)
+ // code set 1: JIS X0208-1990 (a double 8-bit byte set)
+ // restricted to A0-FF in both bytes
+ // code set 2: Half Width Katakana (a single 7-bit byte set)
+ // requiring SS2 as the character prefix
+ // code set 3: JIS X0212-1990 (a double 7-bit byte set)
+ // restricted to A0-FF in both bytes
+ // requiring SS3 as the character prefix
+ EUCPkdFmtJapanese MIB = 18
+
+ // EUCFixWidJapanese is the MIB identifier with IANA name Extended_UNIX_Code_Fixed_Width_for_Japanese.
+ //
+ // Used in Japan. Each character is 2 octets.
+ // code set 0: US-ASCII (a single 7-bit byte set)
+ // 1st byte = 00
+ // 2nd byte = 20-7E
+ // code set 1: JIS X0208-1990 (a double 7-bit byte set)
+ // restricted to A0-FF in both bytes
+ // code set 2: Half Width Katakana (a single 7-bit byte set)
+ // 1st byte = 00
+ // 2nd byte = A0-FF
+ // code set 3: JIS X0212-1990 (a double 7-bit byte set)
+ // restricted to A0-FF in
+ // the first byte
+ // and 21-7E in the second byte
+ EUCFixWidJapanese MIB = 19
+
+ // ISO4UnitedKingdom is the MIB identifier with IANA name BS_4730.
+ //
+ // ISO-IR: International Register of Escape Sequences
+ // Note: The current registration authority is IPSJ/ITSCJ, Japan.
+ // Reference: RFC1345
+ ISO4UnitedKingdom MIB = 20
+
+ // ISO11SwedishForNames is the MIB identifier with IANA name SEN_850200_C.
+ //
+ // ISO-IR: International Register of Escape Sequences
+ // Note: The current registration authority is IPSJ/ITSCJ, Japan.
+ // Reference: RFC1345
+ ISO11SwedishForNames MIB = 21
+
+ // ISO15Italian is the MIB identifier with IANA name IT.
+ //
+ // ISO-IR: International Register of Escape Sequences
+ // Note: The current registration authority is IPSJ/ITSCJ, Japan.
+ // Reference: RFC1345
+ ISO15Italian MIB = 22
+
+ // ISO17Spanish is the MIB identifier with IANA name ES.
+ //
+ // ISO-IR: International Register of Escape Sequences
+ // Note: The current registration authority is IPSJ/ITSCJ, Japan.
+ // Reference: RFC1345
+ ISO17Spanish MIB = 23
+
+ // ISO21German is the MIB identifier with IANA name DIN_66003.
+ //
+ // ISO-IR: International Register of Escape Sequences
+ // Note: The current registration authority is IPSJ/ITSCJ, Japan.
+ // Reference: RFC1345
+ ISO21German MIB = 24
+
+ // ISO60Norwegian1 is the MIB identifier with IANA name NS_4551-1.
+ //
+ // ISO-IR: International Register of Escape Sequences
+ // Note: The current registration authority is IPSJ/ITSCJ, Japan.
+ // Reference: RFC1345
+ ISO60Norwegian1 MIB = 25
+
+ // ISO69French is the MIB identifier with IANA name NF_Z_62-010.
+ //
+ // ISO-IR: International Register of Escape Sequences
+ // Note: The current registration authority is IPSJ/ITSCJ, Japan.
+ // Reference: RFC1345
+ ISO69French MIB = 26
+
+ // ISO10646UTF1 is the MIB identifier with IANA name ISO-10646-UTF-1.
+ //
+ // Universal Transfer Format (1), this is the multibyte
+ // encoding, that subsets ASCII-7. It does not have byte
+ // ordering issues.
+ ISO10646UTF1 MIB = 27
+
+ // ISO646basic1983 is the MIB identifier with IANA name ISO_646.basic:1983.
+ //
+ // ISO-IR: International Register of Escape Sequences
+ // Note: The current registration authority is IPSJ/ITSCJ, Japan.
+ // Reference: RFC1345
+ ISO646basic1983 MIB = 28
+
+ // INVARIANT is the MIB identifier with IANA name INVARIANT.
+ //
+ // Reference: RFC1345
+ INVARIANT MIB = 29
+
+ // ISO2IntlRefVersion is the MIB identifier with IANA name ISO_646.irv:1983.
+ //
+ // ISO-IR: International Register of Escape Sequences
+ // Note: The current registration authority is IPSJ/ITSCJ, Japan.
+ // Reference: RFC1345
+ ISO2IntlRefVersion MIB = 30
+
+ // NATSSEFI is the MIB identifier with IANA name NATS-SEFI.
+ //
+ // ISO-IR: International Register of Escape Sequences
+ // Note: The current registration authority is IPSJ/ITSCJ, Japan.
+ // Reference: RFC1345
+ NATSSEFI MIB = 31
+
+ // NATSSEFIADD is the MIB identifier with IANA name NATS-SEFI-ADD.
+ //
+ // ISO-IR: International Register of Escape Sequences
+ // Note: The current registration authority is IPSJ/ITSCJ, Japan.
+ // Reference: RFC1345
+ NATSSEFIADD MIB = 32
+
+ // NATSDANO is the MIB identifier with IANA name NATS-DANO.
+ //
+ // ISO-IR: International Register of Escape Sequences
+ // Note: The current registration authority is IPSJ/ITSCJ, Japan.
+ // Reference: RFC1345
+ NATSDANO MIB = 33
+
+ // NATSDANOADD is the MIB identifier with IANA name NATS-DANO-ADD.
+ //
+ // ISO-IR: International Register of Escape Sequences
+ // Note: The current registration authority is IPSJ/ITSCJ, Japan.
+ // Reference: RFC1345
+ NATSDANOADD MIB = 34
+
+ // ISO10Swedish is the MIB identifier with IANA name SEN_850200_B.
+ //
+ // ISO-IR: International Register of Escape Sequences
+ // Note: The current registration authority is IPSJ/ITSCJ, Japan.
+ // Reference: RFC1345
+ ISO10Swedish MIB = 35
+
+ // KSC56011987 is the MIB identifier with IANA name KS_C_5601-1987.
+ //
+ // ISO-IR: International Register of Escape Sequences
+ // Note: The current registration authority is IPSJ/ITSCJ, Japan.
+ // Reference: RFC1345
+ KSC56011987 MIB = 36
+
+ // ISO2022KR is the MIB identifier with IANA name ISO-2022-KR (MIME: ISO-2022-KR).
+ //
+ // rfc1557 (see also KS_C_5601-1987)
+ // Reference: RFC1557
+ ISO2022KR MIB = 37
+
+ // EUCKR is the MIB identifier with IANA name EUC-KR (MIME: EUC-KR).
+ //
+ // rfc1557 (see also KS_C_5861-1992)
+ // Reference: RFC1557
+ EUCKR MIB = 38
+
+ // ISO2022JP is the MIB identifier with IANA name ISO-2022-JP (MIME: ISO-2022-JP).
+ //
+ // rfc1468 (see also rfc2237 )
+ // Reference: RFC1468
+ ISO2022JP MIB = 39
+
+ // ISO2022JP2 is the MIB identifier with IANA name ISO-2022-JP-2 (MIME: ISO-2022-JP-2).
+ //
+ // rfc1554
+ // Reference: RFC1554
+ ISO2022JP2 MIB = 40
+
+ // ISO13JISC6220jp is the MIB identifier with IANA name JIS_C6220-1969-jp.
+ //
+ // ISO-IR: International Register of Escape Sequences
+ // Note: The current registration authority is IPSJ/ITSCJ, Japan.
+ // Reference: RFC1345
+ ISO13JISC6220jp MIB = 41
+
+ // ISO14JISC6220ro is the MIB identifier with IANA name JIS_C6220-1969-ro.
+ //
+ // ISO-IR: International Register of Escape Sequences
+ // Note: The current registration authority is IPSJ/ITSCJ, Japan.
+ // Reference: RFC1345
+ ISO14JISC6220ro MIB = 42
+
+ // ISO16Portuguese is the MIB identifier with IANA name PT.
+ //
+ // ISO-IR: International Register of Escape Sequences
+ // Note: The current registration authority is IPSJ/ITSCJ, Japan.
+ // Reference: RFC1345
+ ISO16Portuguese MIB = 43
+
+ // ISO18Greek7Old is the MIB identifier with IANA name greek7-old.
+ //
+ // ISO-IR: International Register of Escape Sequences
+ // Note: The current registration authority is IPSJ/ITSCJ, Japan.
+ // Reference: RFC1345
+ ISO18Greek7Old MIB = 44
+
+ // ISO19LatinGreek is the MIB identifier with IANA name latin-greek.
+ //
+ // ISO-IR: International Register of Escape Sequences
+ // Note: The current registration authority is IPSJ/ITSCJ, Japan.
+ // Reference: RFC1345
+ ISO19LatinGreek MIB = 45
+
+ // ISO25French is the MIB identifier with IANA name NF_Z_62-010_(1973).
+ //
+ // ISO-IR: International Register of Escape Sequences
+ // Note: The current registration authority is IPSJ/ITSCJ, Japan.
+ // Reference: RFC1345
+ ISO25French MIB = 46
+
+ // ISO27LatinGreek1 is the MIB identifier with IANA name Latin-greek-1.
+ //
+ // ISO-IR: International Register of Escape Sequences
+ // Note: The current registration authority is IPSJ/ITSCJ, Japan.
+ // Reference: RFC1345
+ ISO27LatinGreek1 MIB = 47
+
+ // ISO5427Cyrillic is the MIB identifier with IANA name ISO_5427.
+ //
+ // ISO-IR: International Register of Escape Sequences
+ // Note: The current registration authority is IPSJ/ITSCJ, Japan.
+ // Reference: RFC1345
+ ISO5427Cyrillic MIB = 48
+
+ // ISO42JISC62261978 is the MIB identifier with IANA name JIS_C6226-1978.
+ //
+ // ISO-IR: International Register of Escape Sequences
+ // Note: The current registration authority is IPSJ/ITSCJ, Japan.
+ // Reference: RFC1345
+ ISO42JISC62261978 MIB = 49
+
+ // ISO47BSViewdata is the MIB identifier with IANA name BS_viewdata.
+ //
+ // ISO-IR: International Register of Escape Sequences
+ // Note: The current registration authority is IPSJ/ITSCJ, Japan.
+ // Reference: RFC1345
+ ISO47BSViewdata MIB = 50
+
+ // ISO49INIS is the MIB identifier with IANA name INIS.
+ //
+ // ISO-IR: International Register of Escape Sequences
+ // Note: The current registration authority is IPSJ/ITSCJ, Japan.
+ // Reference: RFC1345
+ ISO49INIS MIB = 51
+
+ // ISO50INIS8 is the MIB identifier with IANA name INIS-8.
+ //
+ // ISO-IR: International Register of Escape Sequences
+ // Note: The current registration authority is IPSJ/ITSCJ, Japan.
+ // Reference: RFC1345
+ ISO50INIS8 MIB = 52
+
+ // ISO51INISCyrillic is the MIB identifier with IANA name INIS-cyrillic.
+ //
+ // ISO-IR: International Register of Escape Sequences
+ // Note: The current registration authority is IPSJ/ITSCJ, Japan.
+ // Reference: RFC1345
+ ISO51INISCyrillic MIB = 53
+
+ // ISO54271981 is the MIB identifier with IANA name ISO_5427:1981.
+ //
+ // ISO-IR: International Register of Escape Sequences
+ // Note: The current registration authority is IPSJ/ITSCJ, Japan.
+ // Reference: RFC1345
+ ISO54271981 MIB = 54
+
+ // ISO5428Greek is the MIB identifier with IANA name ISO_5428:1980.
+ //
+ // ISO-IR: International Register of Escape Sequences
+ // Note: The current registration authority is IPSJ/ITSCJ, Japan.
+ // Reference: RFC1345
+ ISO5428Greek MIB = 55
+
+ // ISO57GB1988 is the MIB identifier with IANA name GB_1988-80.
+ //
+ // ISO-IR: International Register of Escape Sequences
+ // Note: The current registration authority is IPSJ/ITSCJ, Japan.
+ // Reference: RFC1345
+ ISO57GB1988 MIB = 56
+
+ // ISO58GB231280 is the MIB identifier with IANA name GB_2312-80.
+ //
+ // ISO-IR: International Register of Escape Sequences
+ // Note: The current registration authority is IPSJ/ITSCJ, Japan.
+ // Reference: RFC1345
+ ISO58GB231280 MIB = 57
+
+ // ISO61Norwegian2 is the MIB identifier with IANA name NS_4551-2.
+ //
+ // ISO-IR: International Register of Escape Sequences
+ // Note: The current registration authority is IPSJ/ITSCJ, Japan.
+ // Reference: RFC1345
+ ISO61Norwegian2 MIB = 58
+
+ // ISO70VideotexSupp1 is the MIB identifier with IANA name videotex-suppl.
+ //
+ // ISO-IR: International Register of Escape Sequences
+ // Note: The current registration authority is IPSJ/ITSCJ, Japan.
+ // Reference: RFC1345
+ ISO70VideotexSupp1 MIB = 59
+
+ // ISO84Portuguese2 is the MIB identifier with IANA name PT2.
+ //
+ // ISO-IR: International Register of Escape Sequences
+ // Note: The current registration authority is IPSJ/ITSCJ, Japan.
+ // Reference: RFC1345
+ ISO84Portuguese2 MIB = 60
+
+ // ISO85Spanish2 is the MIB identifier with IANA name ES2.
+ //
+ // ISO-IR: International Register of Escape Sequences
+ // Note: The current registration authority is IPSJ/ITSCJ, Japan.
+ // Reference: RFC1345
+ ISO85Spanish2 MIB = 61
+
+ // ISO86Hungarian is the MIB identifier with IANA name MSZ_7795.3.
+ //
+ // ISO-IR: International Register of Escape Sequences
+ // Note: The current registration authority is IPSJ/ITSCJ, Japan.
+ // Reference: RFC1345
+ ISO86Hungarian MIB = 62
+
+ // ISO87JISX0208 is the MIB identifier with IANA name JIS_C6226-1983.
+ //
+ // ISO-IR: International Register of Escape Sequences
+ // Note: The current registration authority is IPSJ/ITSCJ, Japan.
+ // Reference: RFC1345
+ ISO87JISX0208 MIB = 63
+
+ // ISO88Greek7 is the MIB identifier with IANA name greek7.
+ //
+ // ISO-IR: International Register of Escape Sequences
+ // Note: The current registration authority is IPSJ/ITSCJ, Japan.
+ // Reference: RFC1345
+ ISO88Greek7 MIB = 64
+
+ // ISO89ASMO449 is the MIB identifier with IANA name ASMO_449.
+ //
+ // ISO-IR: International Register of Escape Sequences
+ // Note: The current registration authority is IPSJ/ITSCJ, Japan.
+ // Reference: RFC1345
+ ISO89ASMO449 MIB = 65
+
+ // ISO90 is the MIB identifier with IANA name iso-ir-90.
+ //
+ // ISO-IR: International Register of Escape Sequences
+ // Note: The current registration authority is IPSJ/ITSCJ, Japan.
+ // Reference: RFC1345
+ ISO90 MIB = 66
+
+ // ISO91JISC62291984a is the MIB identifier with IANA name JIS_C6229-1984-a.
+ //
+ // ISO-IR: International Register of Escape Sequences
+ // Note: The current registration authority is IPSJ/ITSCJ, Japan.
+ // Reference: RFC1345
+ ISO91JISC62291984a MIB = 67
+
+ // ISO92JISC62991984b is the MIB identifier with IANA name JIS_C6229-1984-b.
+ //
+ // ISO-IR: International Register of Escape Sequences
+ // Note: The current registration authority is IPSJ/ITSCJ, Japan.
+ // Reference: RFC1345
+ ISO92JISC62991984b MIB = 68
+
+ // ISO93JIS62291984badd is the MIB identifier with IANA name JIS_C6229-1984-b-add.
+ //
+ // ISO-IR: International Register of Escape Sequences
+ // Note: The current registration authority is IPSJ/ITSCJ, Japan.
+ // Reference: RFC1345
+ ISO93JIS62291984badd MIB = 69
+
+ // ISO94JIS62291984hand is the MIB identifier with IANA name JIS_C6229-1984-hand.
+ //
+ // ISO-IR: International Register of Escape Sequences
+ // Note: The current registration authority is IPSJ/ITSCJ, Japan.
+ // Reference: RFC1345
+ ISO94JIS62291984hand MIB = 70
+
+ // ISO95JIS62291984handadd is the MIB identifier with IANA name JIS_C6229-1984-hand-add.
+ //
+ // ISO-IR: International Register of Escape Sequences
+ // Note: The current registration authority is IPSJ/ITSCJ, Japan.
+ // Reference: RFC1345
+ ISO95JIS62291984handadd MIB = 71
+
+ // ISO96JISC62291984kana is the MIB identifier with IANA name JIS_C6229-1984-kana.
+ //
+ // ISO-IR: International Register of Escape Sequences
+ // Note: The current registration authority is IPSJ/ITSCJ, Japan.
+ // Reference: RFC1345
+ ISO96JISC62291984kana MIB = 72
+
+ // ISO2033 is the MIB identifier with IANA name ISO_2033-1983.
+ //
+ // ISO-IR: International Register of Escape Sequences
+ // Note: The current registration authority is IPSJ/ITSCJ, Japan.
+ // Reference: RFC1345
+ ISO2033 MIB = 73
+
+ // ISO99NAPLPS is the MIB identifier with IANA name ANSI_X3.110-1983.
+ //
+ // ISO-IR: International Register of Escape Sequences
+ // Note: The current registration authority is IPSJ/ITSCJ, Japan.
+ // Reference: RFC1345
+ ISO99NAPLPS MIB = 74
+
+ // ISO102T617bit is the MIB identifier with IANA name T.61-7bit.
+ //
+ // ISO-IR: International Register of Escape Sequences
+ // Note: The current registration authority is IPSJ/ITSCJ, Japan.
+ // Reference: RFC1345
+ ISO102T617bit MIB = 75
+
+ // ISO103T618bit is the MIB identifier with IANA name T.61-8bit.
+ //
+ // ISO-IR: International Register of Escape Sequences
+ // Note: The current registration authority is IPSJ/ITSCJ, Japan.
+ // Reference: RFC1345
+ ISO103T618bit MIB = 76
+
+ // ISO111ECMACyrillic is the MIB identifier with IANA name ECMA-cyrillic.
+ //
+ // ISO registry
+ ISO111ECMACyrillic MIB = 77
+
+ // ISO121Canadian1 is the MIB identifier with IANA name CSA_Z243.4-1985-1.
+ //
+ // ISO-IR: International Register of Escape Sequences
+ // Note: The current registration authority is IPSJ/ITSCJ, Japan.
+ // Reference: RFC1345
+ ISO121Canadian1 MIB = 78
+
+ // ISO122Canadian2 is the MIB identifier with IANA name CSA_Z243.4-1985-2.
+ //
+ // ISO-IR: International Register of Escape Sequences
+ // Note: The current registration authority is IPSJ/ITSCJ, Japan.
+ // Reference: RFC1345
+ ISO122Canadian2 MIB = 79
+
+ // ISO123CSAZ24341985gr is the MIB identifier with IANA name CSA_Z243.4-1985-gr.
+ //
+ // ISO-IR: International Register of Escape Sequences
+ // Note: The current registration authority is IPSJ/ITSCJ, Japan.
+ // Reference: RFC1345
+ ISO123CSAZ24341985gr MIB = 80
+
+ // ISO88596E is the MIB identifier with IANA name ISO_8859-6-E (MIME: ISO-8859-6-E).
+ //
+ // rfc1556
+ // Reference: RFC1556
+ ISO88596E MIB = 81
+
+ // ISO88596I is the MIB identifier with IANA name ISO_8859-6-I (MIME: ISO-8859-6-I).
+ //
+ // rfc1556
+ // Reference: RFC1556
+ ISO88596I MIB = 82
+
+ // ISO128T101G2 is the MIB identifier with IANA name T.101-G2.
+ //
+ // ISO-IR: International Register of Escape Sequences
+ // Note: The current registration authority is IPSJ/ITSCJ, Japan.
+ // Reference: RFC1345
+ ISO128T101G2 MIB = 83
+
+ // ISO88598E is the MIB identifier with IANA name ISO_8859-8-E (MIME: ISO-8859-8-E).
+ //
+ // rfc1556
+ // Reference: RFC1556
+ ISO88598E MIB = 84
+
+ // ISO88598I is the MIB identifier with IANA name ISO_8859-8-I (MIME: ISO-8859-8-I).
+ //
+ // rfc1556
+ // Reference: RFC1556
+ ISO88598I MIB = 85
+
+ // ISO139CSN369103 is the MIB identifier with IANA name CSN_369103.
+ //
+ // ISO-IR: International Register of Escape Sequences
+ // Note: The current registration authority is IPSJ/ITSCJ, Japan.
+ // Reference: RFC1345
+ ISO139CSN369103 MIB = 86
+
+ // ISO141JUSIB1002 is the MIB identifier with IANA name JUS_I.B1.002.
+ //
+ // ISO-IR: International Register of Escape Sequences
+ // Note: The current registration authority is IPSJ/ITSCJ, Japan.
+ // Reference: RFC1345
+ ISO141JUSIB1002 MIB = 87
+
+ // ISO143IECP271 is the MIB identifier with IANA name IEC_P27-1.
+ //
+ // ISO-IR: International Register of Escape Sequences
+ // Note: The current registration authority is IPSJ/ITSCJ, Japan.
+ // Reference: RFC1345
+ ISO143IECP271 MIB = 88
+
+ // ISO146Serbian is the MIB identifier with IANA name JUS_I.B1.003-serb.
+ //
+ // ISO-IR: International Register of Escape Sequences
+ // Note: The current registration authority is IPSJ/ITSCJ, Japan.
+ // Reference: RFC1345
+ ISO146Serbian MIB = 89
+
+ // ISO147Macedonian is the MIB identifier with IANA name JUS_I.B1.003-mac.
+ //
+ // ISO-IR: International Register of Escape Sequences
+ // Note: The current registration authority is IPSJ/ITSCJ, Japan.
+ // Reference: RFC1345
+ ISO147Macedonian MIB = 90
+
+ // ISO150GreekCCITT is the MIB identifier with IANA name greek-ccitt.
+ //
+ // ISO-IR: International Register of Escape Sequences
+ // Note: The current registration authority is IPSJ/ITSCJ, Japan.
+ // Reference: RFC1345
+ ISO150GreekCCITT MIB = 91
+
+ // ISO151Cuba is the MIB identifier with IANA name NC_NC00-10:81.
+ //
+ // ISO-IR: International Register of Escape Sequences
+ // Note: The current registration authority is IPSJ/ITSCJ, Japan.
+ // Reference: RFC1345
+ ISO151Cuba MIB = 92
+
+ // ISO6937Add is the MIB identifier with IANA name ISO_6937-2-25.
+ //
+ // ISO-IR: International Register of Escape Sequences
+ // Note: The current registration authority is IPSJ/ITSCJ, Japan.
+ // Reference: RFC1345
+ ISO6937Add MIB = 93
+
+ // ISO153GOST1976874 is the MIB identifier with IANA name GOST_19768-74.
+ //
+ // ISO-IR: International Register of Escape Sequences
+ // Note: The current registration authority is IPSJ/ITSCJ, Japan.
+ // Reference: RFC1345
+ ISO153GOST1976874 MIB = 94
+
+ // ISO8859Supp is the MIB identifier with IANA name ISO_8859-supp.
+ //
+ // ISO-IR: International Register of Escape Sequences
+ // Note: The current registration authority is IPSJ/ITSCJ, Japan.
+ // Reference: RFC1345
+ ISO8859Supp MIB = 95
+
+ // ISO10367Box is the MIB identifier with IANA name ISO_10367-box.
+ //
+ // ISO-IR: International Register of Escape Sequences
+ // Note: The current registration authority is IPSJ/ITSCJ, Japan.
+ // Reference: RFC1345
+ ISO10367Box MIB = 96
+
+ // ISO158Lap is the MIB identifier with IANA name latin-lap.
+ //
+ // ISO-IR: International Register of Escape Sequences
+ // Note: The current registration authority is IPSJ/ITSCJ, Japan.
+ // Reference: RFC1345
+ ISO158Lap MIB = 97
+
+ // ISO159JISX02121990 is the MIB identifier with IANA name JIS_X0212-1990.
+ //
+ // ISO-IR: International Register of Escape Sequences
+ // Note: The current registration authority is IPSJ/ITSCJ, Japan.
+ // Reference: RFC1345
+ ISO159JISX02121990 MIB = 98
+
+ // ISO646Danish is the MIB identifier with IANA name DS_2089.
+ //
+ // Danish Standard, DS 2089, February 1974
+ // Reference: RFC1345
+ ISO646Danish MIB = 99
+
+ // USDK is the MIB identifier with IANA name us-dk.
+ //
+ // Reference: RFC1345
+ USDK MIB = 100
+
+ // DKUS is the MIB identifier with IANA name dk-us.
+ //
+ // Reference: RFC1345
+ DKUS MIB = 101
+
+ // KSC5636 is the MIB identifier with IANA name KSC5636.
+ //
+ // Reference: RFC1345
+ KSC5636 MIB = 102
+
+ // Unicode11UTF7 is the MIB identifier with IANA name UNICODE-1-1-UTF-7.
+ //
+ // rfc1642
+ // Reference: RFC1642
+ Unicode11UTF7 MIB = 103
+
+ // ISO2022CN is the MIB identifier with IANA name ISO-2022-CN.
+ //
+ // rfc1922
+ // Reference: RFC1922
+ ISO2022CN MIB = 104
+
+ // ISO2022CNEXT is the MIB identifier with IANA name ISO-2022-CN-EXT.
+ //
+ // rfc1922
+ // Reference: RFC1922
+ ISO2022CNEXT MIB = 105
+
+ // UTF8 is the MIB identifier with IANA name UTF-8.
+ //
+ // rfc3629
+ // Reference: RFC3629
+ UTF8 MIB = 106
+
+ // ISO885913 is the MIB identifier with IANA name ISO-8859-13.
+ //
+ // ISO See https://www.iana.org/assignments/charset-reg/ISO-8859-13 https://www.iana.org/assignments/charset-reg/ISO-8859-13
+ ISO885913 MIB = 109
+
+ // ISO885914 is the MIB identifier with IANA name ISO-8859-14.
+ //
+ // ISO See https://www.iana.org/assignments/charset-reg/ISO-8859-14
+ ISO885914 MIB = 110
+
+ // ISO885915 is the MIB identifier with IANA name ISO-8859-15.
+ //
+ // ISO
+ // Please see: https://www.iana.org/assignments/charset-reg/ISO-8859-15
+ ISO885915 MIB = 111
+
+ // ISO885916 is the MIB identifier with IANA name ISO-8859-16.
+ //
+ // ISO
+ ISO885916 MIB = 112
+
+ // GBK is the MIB identifier with IANA name GBK.
+ //
+ // Chinese IT Standardization Technical Committee
+ // Please see: https://www.iana.org/assignments/charset-reg/GBK
+ GBK MIB = 113
+
+ // GB18030 is the MIB identifier with IANA name GB18030.
+ //
+ // Chinese IT Standardization Technical Committee
+ // Please see: https://www.iana.org/assignments/charset-reg/GB18030
+ GB18030 MIB = 114
+
+ // OSDEBCDICDF0415 is the MIB identifier with IANA name OSD_EBCDIC_DF04_15.
+ //
+ // Fujitsu-Siemens standard mainframe EBCDIC encoding
+ // Please see: https://www.iana.org/assignments/charset-reg/OSD-EBCDIC-DF04-15
+ OSDEBCDICDF0415 MIB = 115
+
+ // OSDEBCDICDF03IRV is the MIB identifier with IANA name OSD_EBCDIC_DF03_IRV.
+ //
+ // Fujitsu-Siemens standard mainframe EBCDIC encoding
+ // Please see: https://www.iana.org/assignments/charset-reg/OSD-EBCDIC-DF03-IRV
+ OSDEBCDICDF03IRV MIB = 116
+
+ // OSDEBCDICDF041 is the MIB identifier with IANA name OSD_EBCDIC_DF04_1.
+ //
+ // Fujitsu-Siemens standard mainframe EBCDIC encoding
+ // Please see: https://www.iana.org/assignments/charset-reg/OSD-EBCDIC-DF04-1
+ OSDEBCDICDF041 MIB = 117
+
+ // ISO115481 is the MIB identifier with IANA name ISO-11548-1.
+ //
+ // See https://www.iana.org/assignments/charset-reg/ISO-11548-1
+ ISO115481 MIB = 118
+
+ // KZ1048 is the MIB identifier with IANA name KZ-1048.
+ //
+ // See https://www.iana.org/assignments/charset-reg/KZ-1048
+ KZ1048 MIB = 119
+
+ // Unicode is the MIB identifier with IANA name ISO-10646-UCS-2.
+ //
+ // the 2-octet Basic Multilingual Plane, aka Unicode
+ // this needs to specify network byte order: the standard
+ // does not specify (it is a 16-bit integer space)
+ Unicode MIB = 1000
+
+ // UCS4 is the MIB identifier with IANA name ISO-10646-UCS-4.
+ //
+ // the full code space. (same comment about byte order,
+ // these are 31-bit numbers.
+ UCS4 MIB = 1001
+
+ // UnicodeASCII is the MIB identifier with IANA name ISO-10646-UCS-Basic.
+ //
+ // ASCII subset of Unicode. Basic Latin = collection 1
+ // See ISO 10646, Appendix A
+ UnicodeASCII MIB = 1002
+
+ // UnicodeLatin1 is the MIB identifier with IANA name ISO-10646-Unicode-Latin1.
+ //
+ // ISO Latin-1 subset of Unicode. Basic Latin and Latin-1
+ // Supplement = collections 1 and 2. See ISO 10646,
+ // Appendix A. See rfc1815 .
+ UnicodeLatin1 MIB = 1003
+
+ // UnicodeJapanese is the MIB identifier with IANA name ISO-10646-J-1.
+ //
+ // ISO 10646 Japanese, see rfc1815 .
+ UnicodeJapanese MIB = 1004
+
+ // UnicodeIBM1261 is the MIB identifier with IANA name ISO-Unicode-IBM-1261.
+ //
+ // IBM Latin-2, -3, -5, Extended Presentation Set, GCSGID: 1261
+ UnicodeIBM1261 MIB = 1005
+
+ // UnicodeIBM1268 is the MIB identifier with IANA name ISO-Unicode-IBM-1268.
+ //
+ // IBM Latin-4 Extended Presentation Set, GCSGID: 1268
+ UnicodeIBM1268 MIB = 1006
+
+ // UnicodeIBM1276 is the MIB identifier with IANA name ISO-Unicode-IBM-1276.
+ //
+ // IBM Cyrillic Greek Extended Presentation Set, GCSGID: 1276
+ UnicodeIBM1276 MIB = 1007
+
+ // UnicodeIBM1264 is the MIB identifier with IANA name ISO-Unicode-IBM-1264.
+ //
+ // IBM Arabic Presentation Set, GCSGID: 1264
+ UnicodeIBM1264 MIB = 1008
+
+ // UnicodeIBM1265 is the MIB identifier with IANA name ISO-Unicode-IBM-1265.
+ //
+ // IBM Hebrew Presentation Set, GCSGID: 1265
+ UnicodeIBM1265 MIB = 1009
+
+ // Unicode11 is the MIB identifier with IANA name UNICODE-1-1.
+ //
+ // rfc1641
+ // Reference: RFC1641
+ Unicode11 MIB = 1010
+
+ // SCSU is the MIB identifier with IANA name SCSU.
+ //
+ // SCSU See https://www.iana.org/assignments/charset-reg/SCSU
+ SCSU MIB = 1011
+
+ // UTF7 is the MIB identifier with IANA name UTF-7.
+ //
+ // rfc2152
+ // Reference: RFC2152
+ UTF7 MIB = 1012
+
+ // UTF16BE is the MIB identifier with IANA name UTF-16BE.
+ //
+ // rfc2781
+ // Reference: RFC2781
+ UTF16BE MIB = 1013
+
+ // UTF16LE is the MIB identifier with IANA name UTF-16LE.
+ //
+ // rfc2781
+ // Reference: RFC2781
+ UTF16LE MIB = 1014
+
+ // UTF16 is the MIB identifier with IANA name UTF-16.
+ //
+ // rfc2781
+ // Reference: RFC2781
+ UTF16 MIB = 1015
+
+ // CESU8 is the MIB identifier with IANA name CESU-8.
+ //
+ // https://www.unicode.org/reports/tr26
+ CESU8 MIB = 1016
+
+ // UTF32 is the MIB identifier with IANA name UTF-32.
+ //
+ // https://www.unicode.org/reports/tr19/
+ UTF32 MIB = 1017
+
+ // UTF32BE is the MIB identifier with IANA name UTF-32BE.
+ //
+ // https://www.unicode.org/reports/tr19/
+ UTF32BE MIB = 1018
+
+ // UTF32LE is the MIB identifier with IANA name UTF-32LE.
+ //
+ // https://www.unicode.org/reports/tr19/
+ UTF32LE MIB = 1019
+
+ // BOCU1 is the MIB identifier with IANA name BOCU-1.
+ //
+ // https://www.unicode.org/notes/tn6/
+ BOCU1 MIB = 1020
+
+ // UTF7IMAP is the MIB identifier with IANA name UTF-7-IMAP.
+ //
+ // Note: This charset is used to encode Unicode in IMAP mailbox names;
+ // see section 5.1.3 of rfc3501 . It should never be used
+ // outside this context. A name has been assigned so that charset processing
+ // implementations can refer to it in a consistent way.
+ UTF7IMAP MIB = 1021
+
+ // Windows30Latin1 is the MIB identifier with IANA name ISO-8859-1-Windows-3.0-Latin-1.
+ //
+ // Extended ISO 8859-1 Latin-1 for Windows 3.0.
+ // PCL Symbol Set id: 9U
+ Windows30Latin1 MIB = 2000
+
+ // Windows31Latin1 is the MIB identifier with IANA name ISO-8859-1-Windows-3.1-Latin-1.
+ //
+ // Extended ISO 8859-1 Latin-1 for Windows 3.1.
+ // PCL Symbol Set id: 19U
+ Windows31Latin1 MIB = 2001
+
+ // Windows31Latin2 is the MIB identifier with IANA name ISO-8859-2-Windows-Latin-2.
+ //
+ // Extended ISO 8859-2. Latin-2 for Windows 3.1.
+ // PCL Symbol Set id: 9E
+ Windows31Latin2 MIB = 2002
+
+ // Windows31Latin5 is the MIB identifier with IANA name ISO-8859-9-Windows-Latin-5.
+ //
+ // Extended ISO 8859-9. Latin-5 for Windows 3.1
+ // PCL Symbol Set id: 5T
+ Windows31Latin5 MIB = 2003
+
+ // HPRoman8 is the MIB identifier with IANA name hp-roman8.
+ //
+ // LaserJet IIP Printer User's Manual,
+ // HP part no 33471-90901, Hewlet-Packard, June 1989.
+ // Reference: RFC1345
+ HPRoman8 MIB = 2004
+
+ // AdobeStandardEncoding is the MIB identifier with IANA name Adobe-Standard-Encoding.
+ //
+ // PostScript Language Reference Manual
+ // PCL Symbol Set id: 10J
+ AdobeStandardEncoding MIB = 2005
+
+ // VenturaUS is the MIB identifier with IANA name Ventura-US.
+ //
+ // Ventura US. ASCII plus characters typically used in
+ // publishing, like pilcrow, copyright, registered, trade mark,
+ // section, dagger, and double dagger in the range A0 (hex)
+ // to FF (hex).
+ // PCL Symbol Set id: 14J
+ VenturaUS MIB = 2006
+
+ // VenturaInternational is the MIB identifier with IANA name Ventura-International.
+ //
+ // Ventura International. ASCII plus coded characters similar
+ // to Roman8.
+ // PCL Symbol Set id: 13J
+ VenturaInternational MIB = 2007
+
+ // DECMCS is the MIB identifier with IANA name DEC-MCS.
+ //
+ // VAX/VMS User's Manual,
+ // Order Number: AI-Y517A-TE, April 1986.
+ // Reference: RFC1345
+ DECMCS MIB = 2008
+
+ // PC850Multilingual is the MIB identifier with IANA name IBM850.
+ //
+ // IBM NLS RM Vol2 SE09-8002-01, March 1990
+ // Reference: RFC1345
+ PC850Multilingual MIB = 2009
+
+ // PC8DanishNorwegian is the MIB identifier with IANA name PC8-Danish-Norwegian.
+ //
+ // PC Danish Norwegian
+ // 8-bit PC set for Danish Norwegian
+ // PCL Symbol Set id: 11U
+ PC8DanishNorwegian MIB = 2012
+
+ // PC862LatinHebrew is the MIB identifier with IANA name IBM862.
+ //
+ // IBM NLS RM Vol2 SE09-8002-01, March 1990
+ // Reference: RFC1345
+ PC862LatinHebrew MIB = 2013
+
+ // PC8Turkish is the MIB identifier with IANA name PC8-Turkish.
+ //
+ // PC Latin Turkish. PCL Symbol Set id: 9T
+ PC8Turkish MIB = 2014
+
+ // IBMSymbols is the MIB identifier with IANA name IBM-Symbols.
+ //
+ // Presentation Set, CPGID: 259
+ IBMSymbols MIB = 2015
+
+ // IBMThai is the MIB identifier with IANA name IBM-Thai.
+ //
+ // Presentation Set, CPGID: 838
+ IBMThai MIB = 2016
+
+ // HPLegal is the MIB identifier with IANA name HP-Legal.
+ //
+ // PCL 5 Comparison Guide, Hewlett-Packard,
+ // HP part number 5961-0510, October 1992
+ // PCL Symbol Set id: 1U
+ HPLegal MIB = 2017
+
+ // HPPiFont is the MIB identifier with IANA name HP-Pi-font.
+ //
+ // PCL 5 Comparison Guide, Hewlett-Packard,
+ // HP part number 5961-0510, October 1992
+ // PCL Symbol Set id: 15U
+ HPPiFont MIB = 2018
+
+ // HPMath8 is the MIB identifier with IANA name HP-Math8.
+ //
+ // PCL 5 Comparison Guide, Hewlett-Packard,
+ // HP part number 5961-0510, October 1992
+ // PCL Symbol Set id: 8M
+ HPMath8 MIB = 2019
+
+ // HPPSMath is the MIB identifier with IANA name Adobe-Symbol-Encoding.
+ //
+ // PostScript Language Reference Manual
+ // PCL Symbol Set id: 5M
+ HPPSMath MIB = 2020
+
+ // HPDesktop is the MIB identifier with IANA name HP-DeskTop.
+ //
+ // PCL 5 Comparison Guide, Hewlett-Packard,
+ // HP part number 5961-0510, October 1992
+ // PCL Symbol Set id: 7J
+ HPDesktop MIB = 2021
+
+ // VenturaMath is the MIB identifier with IANA name Ventura-Math.
+ //
+ // PCL 5 Comparison Guide, Hewlett-Packard,
+ // HP part number 5961-0510, October 1992
+ // PCL Symbol Set id: 6M
+ VenturaMath MIB = 2022
+
+ // MicrosoftPublishing is the MIB identifier with IANA name Microsoft-Publishing.
+ //
+ // PCL 5 Comparison Guide, Hewlett-Packard,
+ // HP part number 5961-0510, October 1992
+ // PCL Symbol Set id: 6J
+ MicrosoftPublishing MIB = 2023
+
+ // Windows31J is the MIB identifier with IANA name Windows-31J.
+ //
+ // Windows Japanese. A further extension of Shift_JIS
+ // to include NEC special characters (Row 13), NEC
+ // selection of IBM extensions (Rows 89 to 92), and IBM
+ // extensions (Rows 115 to 119). The CCS's are
+ // JIS X0201:1997, JIS X0208:1997, and these extensions.
+ // This charset can be used for the top-level media type "text",
+ // but it is of limited or specialized use (see rfc2278 ).
+ // PCL Symbol Set id: 19K
+ Windows31J MIB = 2024
+
+ // GB2312 is the MIB identifier with IANA name GB2312 (MIME: GB2312).
+ //
+ // Chinese for People's Republic of China (PRC) mixed one byte,
+ // two byte set:
+ // 20-7E = one byte ASCII
+ // A1-FE = two byte PRC Kanji
+ // See GB 2312-80
+ // PCL Symbol Set Id: 18C
+ GB2312 MIB = 2025
+
+ // Big5 is the MIB identifier with IANA name Big5 (MIME: Big5).
+ //
+ // Chinese for Taiwan Multi-byte set.
+ // PCL Symbol Set Id: 18T
+ Big5 MIB = 2026
+
+ // Macintosh is the MIB identifier with IANA name macintosh.
+ //
+ // The Unicode Standard ver1.0, ISBN 0-201-56788-1, Oct 1991
+ // Reference: RFC1345
+ Macintosh MIB = 2027
+
+ // IBM037 is the MIB identifier with IANA name IBM037.
+ //
+ // IBM NLS RM Vol2 SE09-8002-01, March 1990
+ // Reference: RFC1345
+ IBM037 MIB = 2028
+
+ // IBM038 is the MIB identifier with IANA name IBM038.
+ //
+ // IBM 3174 Character Set Ref, GA27-3831-02, March 1990
+ // Reference: RFC1345
+ IBM038 MIB = 2029
+
+ // IBM273 is the MIB identifier with IANA name IBM273.
+ //
+ // IBM NLS RM Vol2 SE09-8002-01, March 1990
+ // Reference: RFC1345
+ IBM273 MIB = 2030
+
+ // IBM274 is the MIB identifier with IANA name IBM274.
+ //
+ // IBM 3174 Character Set Ref, GA27-3831-02, March 1990
+ // Reference: RFC1345
+ IBM274 MIB = 2031
+
+ // IBM275 is the MIB identifier with IANA name IBM275.
+ //
+ // IBM NLS RM Vol2 SE09-8002-01, March 1990
+ // Reference: RFC1345
+ IBM275 MIB = 2032
+
+ // IBM277 is the MIB identifier with IANA name IBM277.
+ //
+ // IBM NLS RM Vol2 SE09-8002-01, March 1990
+ // Reference: RFC1345
+ IBM277 MIB = 2033
+
+ // IBM278 is the MIB identifier with IANA name IBM278.
+ //
+ // IBM NLS RM Vol2 SE09-8002-01, March 1990
+ // Reference: RFC1345
+ IBM278 MIB = 2034
+
+ // IBM280 is the MIB identifier with IANA name IBM280.
+ //
+ // IBM NLS RM Vol2 SE09-8002-01, March 1990
+ // Reference: RFC1345
+ IBM280 MIB = 2035
+
+ // IBM281 is the MIB identifier with IANA name IBM281.
+ //
+ // IBM 3174 Character Set Ref, GA27-3831-02, March 1990
+ // Reference: RFC1345
+ IBM281 MIB = 2036
+
+ // IBM284 is the MIB identifier with IANA name IBM284.
+ //
+ // IBM NLS RM Vol2 SE09-8002-01, March 1990
+ // Reference: RFC1345
+ IBM284 MIB = 2037
+
+ // IBM285 is the MIB identifier with IANA name IBM285.
+ //
+ // IBM NLS RM Vol2 SE09-8002-01, March 1990
+ // Reference: RFC1345
+ IBM285 MIB = 2038
+
+ // IBM290 is the MIB identifier with IANA name IBM290.
+ //
+ // IBM 3174 Character Set Ref, GA27-3831-02, March 1990
+ // Reference: RFC1345
+ IBM290 MIB = 2039
+
+ // IBM297 is the MIB identifier with IANA name IBM297.
+ //
+ // IBM NLS RM Vol2 SE09-8002-01, March 1990
+ // Reference: RFC1345
+ IBM297 MIB = 2040
+
+ // IBM420 is the MIB identifier with IANA name IBM420.
+ //
+ // IBM NLS RM Vol2 SE09-8002-01, March 1990,
+ // IBM NLS RM p 11-11
+ // Reference: RFC1345
+ IBM420 MIB = 2041
+
+ // IBM423 is the MIB identifier with IANA name IBM423.
+ //
+ // IBM NLS RM Vol2 SE09-8002-01, March 1990
+ // Reference: RFC1345
+ IBM423 MIB = 2042
+
+ // IBM424 is the MIB identifier with IANA name IBM424.
+ //
+ // IBM NLS RM Vol2 SE09-8002-01, March 1990
+ // Reference: RFC1345
+ IBM424 MIB = 2043
+
+ // PC8CodePage437 is the MIB identifier with IANA name IBM437.
+ //
+ // IBM NLS RM Vol2 SE09-8002-01, March 1990
+ // Reference: RFC1345
+ PC8CodePage437 MIB = 2011
+
+ // IBM500 is the MIB identifier with IANA name IBM500.
+ //
+ // IBM NLS RM Vol2 SE09-8002-01, March 1990
+ // Reference: RFC1345
+ IBM500 MIB = 2044
+
+ // IBM851 is the MIB identifier with IANA name IBM851.
+ //
+ // IBM NLS RM Vol2 SE09-8002-01, March 1990
+ // Reference: RFC1345
+ IBM851 MIB = 2045
+
+ // PCp852 is the MIB identifier with IANA name IBM852.
+ //
+ // IBM NLS RM Vol2 SE09-8002-01, March 1990
+ // Reference: RFC1345
+ PCp852 MIB = 2010
+
+ // IBM855 is the MIB identifier with IANA name IBM855.
+ //
+ // IBM NLS RM Vol2 SE09-8002-01, March 1990
+ // Reference: RFC1345
+ IBM855 MIB = 2046
+
+ // IBM857 is the MIB identifier with IANA name IBM857.
+ //
+ // IBM NLS RM Vol2 SE09-8002-01, March 1990
+ // Reference: RFC1345
+ IBM857 MIB = 2047
+
+ // IBM860 is the MIB identifier with IANA name IBM860.
+ //
+ // IBM NLS RM Vol2 SE09-8002-01, March 1990
+ // Reference: RFC1345
+ IBM860 MIB = 2048
+
+ // IBM861 is the MIB identifier with IANA name IBM861.
+ //
+ // IBM NLS RM Vol2 SE09-8002-01, March 1990
+ // Reference: RFC1345
+ IBM861 MIB = 2049
+
+ // IBM863 is the MIB identifier with IANA name IBM863.
+ //
+ // IBM Keyboard layouts and code pages, PN 07G4586 June 1991
+ // Reference: RFC1345
+ IBM863 MIB = 2050
+
+ // IBM864 is the MIB identifier with IANA name IBM864.
+ //
+ // IBM Keyboard layouts and code pages, PN 07G4586 June 1991
+ // Reference: RFC1345
+ IBM864 MIB = 2051
+
+ // IBM865 is the MIB identifier with IANA name IBM865.
+ //
+ // IBM DOS 3.3 Ref (Abridged), 94X9575 (Feb 1987)
+ // Reference: RFC1345
+ IBM865 MIB = 2052
+
+ // IBM868 is the MIB identifier with IANA name IBM868.
+ //
+ // IBM NLS RM Vol2 SE09-8002-01, March 1990
+ // Reference: RFC1345
+ IBM868 MIB = 2053
+
+ // IBM869 is the MIB identifier with IANA name IBM869.
+ //
+ // IBM Keyboard layouts and code pages, PN 07G4586 June 1991
+ // Reference: RFC1345
+ IBM869 MIB = 2054
+
+ // IBM870 is the MIB identifier with IANA name IBM870.
+ //
+ // IBM NLS RM Vol2 SE09-8002-01, March 1990
+ // Reference: RFC1345
+ IBM870 MIB = 2055
+
+ // IBM871 is the MIB identifier with IANA name IBM871.
+ //
+ // IBM NLS RM Vol2 SE09-8002-01, March 1990
+ // Reference: RFC1345
+ IBM871 MIB = 2056
+
+ // IBM880 is the MIB identifier with IANA name IBM880.
+ //
+ // IBM NLS RM Vol2 SE09-8002-01, March 1990
+ // Reference: RFC1345
+ IBM880 MIB = 2057
+
+ // IBM891 is the MIB identifier with IANA name IBM891.
+ //
+ // IBM NLS RM Vol2 SE09-8002-01, March 1990
+ // Reference: RFC1345
+ IBM891 MIB = 2058
+
+ // IBM903 is the MIB identifier with IANA name IBM903.
+ //
+ // IBM NLS RM Vol2 SE09-8002-01, March 1990
+ // Reference: RFC1345
+ IBM903 MIB = 2059
+
+ // IBBM904 is the MIB identifier with IANA name IBM904.
+ //
+ // IBM NLS RM Vol2 SE09-8002-01, March 1990
+ // Reference: RFC1345
+ IBBM904 MIB = 2060
+
+ // IBM905 is the MIB identifier with IANA name IBM905.
+ //
+ // IBM 3174 Character Set Ref, GA27-3831-02, March 1990
+ // Reference: RFC1345
+ IBM905 MIB = 2061
+
+ // IBM918 is the MIB identifier with IANA name IBM918.
+ //
+ // IBM NLS RM Vol2 SE09-8002-01, March 1990
+ // Reference: RFC1345
+ IBM918 MIB = 2062
+
+ // IBM1026 is the MIB identifier with IANA name IBM1026.
+ //
+ // IBM NLS RM Vol2 SE09-8002-01, March 1990
+ // Reference: RFC1345
+ IBM1026 MIB = 2063
+
+ // IBMEBCDICATDE is the MIB identifier with IANA name EBCDIC-AT-DE.
+ //
+ // IBM 3270 Char Set Ref Ch 10, GA27-2837-9, April 1987
+ // Reference: RFC1345
+ IBMEBCDICATDE MIB = 2064
+
+ // EBCDICATDEA is the MIB identifier with IANA name EBCDIC-AT-DE-A.
+ //
+ // IBM 3270 Char Set Ref Ch 10, GA27-2837-9, April 1987
+ // Reference: RFC1345
+ EBCDICATDEA MIB = 2065
+
+ // EBCDICCAFR is the MIB identifier with IANA name EBCDIC-CA-FR.
+ //
+ // IBM 3270 Char Set Ref Ch 10, GA27-2837-9, April 1987
+ // Reference: RFC1345
+ EBCDICCAFR MIB = 2066
+
+ // EBCDICDKNO is the MIB identifier with IANA name EBCDIC-DK-NO.
+ //
+ // IBM 3270 Char Set Ref Ch 10, GA27-2837-9, April 1987
+ // Reference: RFC1345
+ EBCDICDKNO MIB = 2067
+
+ // EBCDICDKNOA is the MIB identifier with IANA name EBCDIC-DK-NO-A.
+ //
+ // IBM 3270 Char Set Ref Ch 10, GA27-2837-9, April 1987
+ // Reference: RFC1345
+ EBCDICDKNOA MIB = 2068
+
+ // EBCDICFISE is the MIB identifier with IANA name EBCDIC-FI-SE.
+ //
+ // IBM 3270 Char Set Ref Ch 10, GA27-2837-9, April 1987
+ // Reference: RFC1345
+ EBCDICFISE MIB = 2069
+
+ // EBCDICFISEA is the MIB identifier with IANA name EBCDIC-FI-SE-A.
+ //
+ // IBM 3270 Char Set Ref Ch 10, GA27-2837-9, April 1987
+ // Reference: RFC1345
+ EBCDICFISEA MIB = 2070
+
+ // EBCDICFR is the MIB identifier with IANA name EBCDIC-FR.
+ //
+ // IBM 3270 Char Set Ref Ch 10, GA27-2837-9, April 1987
+ // Reference: RFC1345
+ EBCDICFR MIB = 2071
+
+ // EBCDICIT is the MIB identifier with IANA name EBCDIC-IT.
+ //
+ // IBM 3270 Char Set Ref Ch 10, GA27-2837-9, April 1987
+ // Reference: RFC1345
+ EBCDICIT MIB = 2072
+
+ // EBCDICPT is the MIB identifier with IANA name EBCDIC-PT.
+ //
+ // IBM 3270 Char Set Ref Ch 10, GA27-2837-9, April 1987
+ // Reference: RFC1345
+ EBCDICPT MIB = 2073
+
+ // EBCDICES is the MIB identifier with IANA name EBCDIC-ES.
+ //
+ // IBM 3270 Char Set Ref Ch 10, GA27-2837-9, April 1987
+ // Reference: RFC1345
+ EBCDICES MIB = 2074
+
+ // EBCDICESA is the MIB identifier with IANA name EBCDIC-ES-A.
+ //
+ // IBM 3270 Char Set Ref Ch 10, GA27-2837-9, April 1987
+ // Reference: RFC1345
+ EBCDICESA MIB = 2075
+
+ // EBCDICESS is the MIB identifier with IANA name EBCDIC-ES-S.
+ //
+ // IBM 3270 Char Set Ref Ch 10, GA27-2837-9, April 1987
+ // Reference: RFC1345
+ EBCDICESS MIB = 2076
+
+ // EBCDICUK is the MIB identifier with IANA name EBCDIC-UK.
+ //
+ // IBM 3270 Char Set Ref Ch 10, GA27-2837-9, April 1987
+ // Reference: RFC1345
+ EBCDICUK MIB = 2077
+
+ // EBCDICUS is the MIB identifier with IANA name EBCDIC-US.
+ //
+ // IBM 3270 Char Set Ref Ch 10, GA27-2837-9, April 1987
+ // Reference: RFC1345
+ EBCDICUS MIB = 2078
+
+ // Unknown8BiT is the MIB identifier with IANA name UNKNOWN-8BIT.
+ //
+ // Reference: RFC1428
+ Unknown8BiT MIB = 2079
+
+ // Mnemonic is the MIB identifier with IANA name MNEMONIC.
+ //
+ // rfc1345 , also known as "mnemonic+ascii+38"
+ // Reference: RFC1345
+ Mnemonic MIB = 2080
+
+ // Mnem is the MIB identifier with IANA name MNEM.
+ //
+ // rfc1345 , also known as "mnemonic+ascii+8200"
+ // Reference: RFC1345
+ Mnem MIB = 2081
+
+ // VISCII is the MIB identifier with IANA name VISCII.
+ //
+ // rfc1456
+ // Reference: RFC1456
+ VISCII MIB = 2082
+
+ // VIQR is the MIB identifier with IANA name VIQR.
+ //
+ // rfc1456
+ // Reference: RFC1456
+ VIQR MIB = 2083
+
+ // KOI8R is the MIB identifier with IANA name KOI8-R (MIME: KOI8-R).
+ //
+ // rfc1489 , based on GOST-19768-74, ISO-6937/8,
+ // INIS-Cyrillic, ISO-5427.
+ // Reference: RFC1489
+ KOI8R MIB = 2084
+
+ // HZGB2312 is the MIB identifier with IANA name HZ-GB-2312.
+ //
+ // rfc1842 , rfc1843 rfc1843 rfc1842
+ HZGB2312 MIB = 2085
+
+ // IBM866 is the MIB identifier with IANA name IBM866.
+ //
+ // IBM NLDG Volume 2 (SE09-8002-03) August 1994
+ IBM866 MIB = 2086
+
+ // PC775Baltic is the MIB identifier with IANA name IBM775.
+ //
+ // HP PCL 5 Comparison Guide (P/N 5021-0329) pp B-13, 1996
+ PC775Baltic MIB = 2087
+
+ // KOI8U is the MIB identifier with IANA name KOI8-U.
+ //
+ // rfc2319
+ // Reference: RFC2319
+ KOI8U MIB = 2088
+
+ // IBM00858 is the MIB identifier with IANA name IBM00858.
+ //
+ // IBM See https://www.iana.org/assignments/charset-reg/IBM00858
+ IBM00858 MIB = 2089
+
+ // IBM00924 is the MIB identifier with IANA name IBM00924.
+ //
+ // IBM See https://www.iana.org/assignments/charset-reg/IBM00924
+ IBM00924 MIB = 2090
+
+ // IBM01140 is the MIB identifier with IANA name IBM01140.
+ //
+ // IBM See https://www.iana.org/assignments/charset-reg/IBM01140
+ IBM01140 MIB = 2091
+
+ // IBM01141 is the MIB identifier with IANA name IBM01141.
+ //
+ // IBM See https://www.iana.org/assignments/charset-reg/IBM01141
+ IBM01141 MIB = 2092
+
+ // IBM01142 is the MIB identifier with IANA name IBM01142.
+ //
+ // IBM See https://www.iana.org/assignments/charset-reg/IBM01142
+ IBM01142 MIB = 2093
+
+ // IBM01143 is the MIB identifier with IANA name IBM01143.
+ //
+ // IBM See https://www.iana.org/assignments/charset-reg/IBM01143
+ IBM01143 MIB = 2094
+
+ // IBM01144 is the MIB identifier with IANA name IBM01144.
+ //
+ // IBM See https://www.iana.org/assignments/charset-reg/IBM01144
+ IBM01144 MIB = 2095
+
+ // IBM01145 is the MIB identifier with IANA name IBM01145.
+ //
+ // IBM See https://www.iana.org/assignments/charset-reg/IBM01145
+ IBM01145 MIB = 2096
+
+ // IBM01146 is the MIB identifier with IANA name IBM01146.
+ //
+ // IBM See https://www.iana.org/assignments/charset-reg/IBM01146
+ IBM01146 MIB = 2097
+
+ // IBM01147 is the MIB identifier with IANA name IBM01147.
+ //
+ // IBM See https://www.iana.org/assignments/charset-reg/IBM01147
+ IBM01147 MIB = 2098
+
+ // IBM01148 is the MIB identifier with IANA name IBM01148.
+ //
+ // IBM See https://www.iana.org/assignments/charset-reg/IBM01148
+ IBM01148 MIB = 2099
+
+ // IBM01149 is the MIB identifier with IANA name IBM01149.
+ //
+ // IBM See https://www.iana.org/assignments/charset-reg/IBM01149
+ IBM01149 MIB = 2100
+
+ // Big5HKSCS is the MIB identifier with IANA name Big5-HKSCS.
+ //
+ // See https://www.iana.org/assignments/charset-reg/Big5-HKSCS
+ Big5HKSCS MIB = 2101
+
+ // IBM1047 is the MIB identifier with IANA name IBM1047.
+ //
+ // IBM1047 (EBCDIC Latin 1/Open Systems) https://www-1.ibm.com/servers/eserver/iseries/software/globalization/pdf/cp01047z.pdf
+ IBM1047 MIB = 2102
+
+ // PTCP154 is the MIB identifier with IANA name PTCP154.
+ //
+ // See https://www.iana.org/assignments/charset-reg/PTCP154
+ PTCP154 MIB = 2103
+
+ // Amiga1251 is the MIB identifier with IANA name Amiga-1251.
+ //
+ // See https://www.amiga.ultranet.ru/Amiga-1251.html
+ Amiga1251 MIB = 2104
+
+ // KOI7switched is the MIB identifier with IANA name KOI7-switched.
+ //
+ // See https://www.iana.org/assignments/charset-reg/KOI7-switched
+ KOI7switched MIB = 2105
+
+ // BRF is the MIB identifier with IANA name BRF.
+ //
+ // See https://www.iana.org/assignments/charset-reg/BRF
+ BRF MIB = 2106
+
+ // TSCII is the MIB identifier with IANA name TSCII.
+ //
+ // See https://www.iana.org/assignments/charset-reg/TSCII
+ TSCII MIB = 2107
+
+ // CP51932 is the MIB identifier with IANA name CP51932.
+ //
+ // See https://www.iana.org/assignments/charset-reg/CP51932
+ CP51932 MIB = 2108
+
+ // Windows874 is the MIB identifier with IANA name windows-874.
+ //
+ // See https://www.iana.org/assignments/charset-reg/windows-874
+ Windows874 MIB = 2109
+
+ // Windows1250 is the MIB identifier with IANA name windows-1250.
+ //
+ // Microsoft https://www.iana.org/assignments/charset-reg/windows-1250
+ Windows1250 MIB = 2250
+
+ // Windows1251 is the MIB identifier with IANA name windows-1251.
+ //
+ // Microsoft https://www.iana.org/assignments/charset-reg/windows-1251
+ Windows1251 MIB = 2251
+
+ // Windows1252 is the MIB identifier with IANA name windows-1252.
+ //
+ // Microsoft https://www.iana.org/assignments/charset-reg/windows-1252
+ Windows1252 MIB = 2252
+
+ // Windows1253 is the MIB identifier with IANA name windows-1253.
+ //
+ // Microsoft https://www.iana.org/assignments/charset-reg/windows-1253
+ Windows1253 MIB = 2253
+
+ // Windows1254 is the MIB identifier with IANA name windows-1254.
+ //
+ // Microsoft https://www.iana.org/assignments/charset-reg/windows-1254
+ Windows1254 MIB = 2254
+
+ // Windows1255 is the MIB identifier with IANA name windows-1255.
+ //
+ // Microsoft https://www.iana.org/assignments/charset-reg/windows-1255
+ Windows1255 MIB = 2255
+
+ // Windows1256 is the MIB identifier with IANA name windows-1256.
+ //
+ // Microsoft https://www.iana.org/assignments/charset-reg/windows-1256
+ Windows1256 MIB = 2256
+
+ // Windows1257 is the MIB identifier with IANA name windows-1257.
+ //
+ // Microsoft https://www.iana.org/assignments/charset-reg/windows-1257
+ Windows1257 MIB = 2257
+
+ // Windows1258 is the MIB identifier with IANA name windows-1258.
+ //
+ // Microsoft https://www.iana.org/assignments/charset-reg/windows-1258
+ Windows1258 MIB = 2258
+
+ // TIS620 is the MIB identifier with IANA name TIS-620.
+ //
+ // Thai Industrial Standards Institute (TISI)
+ TIS620 MIB = 2259
+
+ // CP50220 is the MIB identifier with IANA name CP50220.
+ //
+ // See https://www.iana.org/assignments/charset-reg/CP50220
+ CP50220 MIB = 2260
+)
diff --git a/vendor/golang.org/x/text/encoding/internal/internal.go b/vendor/golang.org/x/text/encoding/internal/internal.go
new file mode 100644
index 000000000..413e6fc6d
--- /dev/null
+++ b/vendor/golang.org/x/text/encoding/internal/internal.go
@@ -0,0 +1,75 @@
+// Copyright 2015 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.
+
+// Package internal contains code that is shared among encoding implementations.
+package internal
+
+import (
+ "golang.org/x/text/encoding"
+ "golang.org/x/text/encoding/internal/identifier"
+ "golang.org/x/text/transform"
+)
+
+// Encoding is an implementation of the Encoding interface that adds the String
+// and ID methods to an existing encoding.
+type Encoding struct {
+ encoding.Encoding
+ Name string
+ MIB identifier.MIB
+}
+
+// _ verifies that Encoding implements identifier.Interface.
+var _ identifier.Interface = (*Encoding)(nil)
+
+func (e *Encoding) String() string {
+ return e.Name
+}
+
+func (e *Encoding) ID() (mib identifier.MIB, other string) {
+ return e.MIB, ""
+}
+
+// SimpleEncoding is an Encoding that combines two Transformers.
+type SimpleEncoding struct {
+ Decoder transform.Transformer
+ Encoder transform.Transformer
+}
+
+func (e *SimpleEncoding) NewDecoder() *encoding.Decoder {
+ return &encoding.Decoder{Transformer: e.Decoder}
+}
+
+func (e *SimpleEncoding) NewEncoder() *encoding.Encoder {
+ return &encoding.Encoder{Transformer: e.Encoder}
+}
+
+// FuncEncoding is an Encoding that combines two functions returning a new
+// Transformer.
+type FuncEncoding struct {
+ Decoder func() transform.Transformer
+ Encoder func() transform.Transformer
+}
+
+func (e FuncEncoding) NewDecoder() *encoding.Decoder {
+ return &encoding.Decoder{Transformer: e.Decoder()}
+}
+
+func (e FuncEncoding) NewEncoder() *encoding.Encoder {
+ return &encoding.Encoder{Transformer: e.Encoder()}
+}
+
+// A RepertoireError indicates a rune is not in the repertoire of a destination
+// encoding. It is associated with an encoding-specific suggested replacement
+// byte.
+type RepertoireError byte
+
+// Error implements the error interface.
+func (r RepertoireError) Error() string {
+ return "encoding: rune not supported by encoding."
+}
+
+// Replacement returns the replacement string associated with this error.
+func (r RepertoireError) Replacement() byte { return byte(r) }
+
+var ErrASCIIReplacement = RepertoireError(encoding.ASCIISub)
diff --git a/vendor/golang.org/x/text/encoding/unicode/override.go b/vendor/golang.org/x/text/encoding/unicode/override.go
new file mode 100644
index 000000000..35d62fcc9
--- /dev/null
+++ b/vendor/golang.org/x/text/encoding/unicode/override.go
@@ -0,0 +1,82 @@
+// Copyright 2015 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.
+
+package unicode
+
+import (
+ "golang.org/x/text/transform"
+)
+
+// BOMOverride returns a new decoder transformer that is identical to fallback,
+// except that the presence of a Byte Order Mark at the start of the input
+// causes it to switch to the corresponding Unicode decoding. It will only
+// consider BOMs for UTF-8, UTF-16BE, and UTF-16LE.
+//
+// This differs from using ExpectBOM by allowing a BOM to switch to UTF-8, not
+// just UTF-16 variants, and allowing falling back to any encoding scheme.
+//
+// This technique is recommended by the W3C for use in HTML 5: "For
+// compatibility with deployed content, the byte order mark (also known as BOM)
+// is considered more authoritative than anything else."
+// http://www.w3.org/TR/encoding/#specification-hooks
+//
+// Using BOMOverride is mostly intended for use cases where the first characters
+// of a fallback encoding are known to not be a BOM, for example, for valid HTML
+// and most encodings.
+func BOMOverride(fallback transform.Transformer) transform.Transformer {
+ // TODO: possibly allow a variadic argument of unicode encodings to allow
+ // specifying details of which fallbacks are supported as well as
+ // specifying the details of the implementations. This would also allow for
+ // support for UTF-32, which should not be supported by default.
+ return &bomOverride{fallback: fallback}
+}
+
+type bomOverride struct {
+ fallback transform.Transformer
+ current transform.Transformer
+}
+
+func (d *bomOverride) Reset() {
+ d.current = nil
+ d.fallback.Reset()
+}
+
+var (
+ // TODO: we could use decode functions here, instead of allocating a new
+ // decoder on every NewDecoder as IgnoreBOM decoders can be stateless.
+ utf16le = UTF16(LittleEndian, IgnoreBOM)
+ utf16be = UTF16(BigEndian, IgnoreBOM)
+)
+
+const utf8BOM = "\ufeff"
+
+func (d *bomOverride) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) {
+ if d.current != nil {
+ return d.current.Transform(dst, src, atEOF)
+ }
+ if len(src) < 3 && !atEOF {
+ return 0, 0, transform.ErrShortSrc
+ }
+ d.current = d.fallback
+ bomSize := 0
+ if len(src) >= 2 {
+ if src[0] == 0xFF && src[1] == 0xFE {
+ d.current = utf16le.NewDecoder()
+ bomSize = 2
+ } else if src[0] == 0xFE && src[1] == 0xFF {
+ d.current = utf16be.NewDecoder()
+ bomSize = 2
+ } else if len(src) >= 3 &&
+ src[0] == utf8BOM[0] &&
+ src[1] == utf8BOM[1] &&
+ src[2] == utf8BOM[2] {
+ d.current = transform.Nop
+ bomSize = 3
+ }
+ }
+ if bomSize < len(src) {
+ nDst, nSrc, err = d.current.Transform(dst, src[bomSize:], atEOF)
+ }
+ return nDst, nSrc + bomSize, err
+}
diff --git a/vendor/golang.org/x/text/encoding/unicode/unicode.go b/vendor/golang.org/x/text/encoding/unicode/unicode.go
new file mode 100644
index 000000000..dd99ad14d
--- /dev/null
+++ b/vendor/golang.org/x/text/encoding/unicode/unicode.go
@@ -0,0 +1,512 @@
+// Copyright 2013 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.
+
+// Package unicode provides Unicode encodings such as UTF-16.
+package unicode // import "golang.org/x/text/encoding/unicode"
+
+import (
+ "bytes"
+ "errors"
+ "unicode/utf16"
+ "unicode/utf8"
+
+ "golang.org/x/text/encoding"
+ "golang.org/x/text/encoding/internal"
+ "golang.org/x/text/encoding/internal/identifier"
+ "golang.org/x/text/internal/utf8internal"
+ "golang.org/x/text/runes"
+ "golang.org/x/text/transform"
+)
+
+// TODO: I think the Transformers really should return errors on unmatched
+// surrogate pairs and odd numbers of bytes. This is not required by RFC 2781,
+// which leaves it open, but is suggested by WhatWG. It will allow for all error
+// modes as defined by WhatWG: fatal, HTML and Replacement. This would require
+// the introduction of some kind of error type for conveying the erroneous code
+// point.
+
+// UTF8 is the UTF-8 encoding. It neither removes nor adds byte order marks.
+var UTF8 encoding.Encoding = utf8enc
+
+// UTF8BOM is an UTF-8 encoding where the decoder strips a leading byte order
+// mark while the encoder adds one.
+//
+// Some editors add a byte order mark as a signature to UTF-8 files. Although
+// the byte order mark is not useful for detecting byte order in UTF-8, it is
+// sometimes used as a convention to mark UTF-8-encoded files. This relies on
+// the observation that the UTF-8 byte order mark is either an illegal or at
+// least very unlikely sequence in any other character encoding.
+var UTF8BOM encoding.Encoding = utf8bomEncoding{}
+
+type utf8bomEncoding struct{}
+
+func (utf8bomEncoding) String() string {
+ return "UTF-8-BOM"
+}
+
+func (utf8bomEncoding) ID() (identifier.MIB, string) {
+ return identifier.Unofficial, "x-utf8bom"
+}
+
+func (utf8bomEncoding) NewEncoder() *encoding.Encoder {
+ return &encoding.Encoder{
+ Transformer: &utf8bomEncoder{t: runes.ReplaceIllFormed()},
+ }
+}
+
+func (utf8bomEncoding) NewDecoder() *encoding.Decoder {
+ return &encoding.Decoder{Transformer: &utf8bomDecoder{}}
+}
+
+var utf8enc = &internal.Encoding{
+ &internal.SimpleEncoding{utf8Decoder{}, runes.ReplaceIllFormed()},
+ "UTF-8",
+ identifier.UTF8,
+}
+
+type utf8bomDecoder struct {
+ checked bool
+}
+
+func (t *utf8bomDecoder) Reset() {
+ t.checked = false
+}
+
+func (t *utf8bomDecoder) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) {
+ if !t.checked {
+ if !atEOF && len(src) < len(utf8BOM) {
+ if len(src) == 0 {
+ return 0, 0, nil
+ }
+ return 0, 0, transform.ErrShortSrc
+ }
+ if bytes.HasPrefix(src, []byte(utf8BOM)) {
+ nSrc += len(utf8BOM)
+ src = src[len(utf8BOM):]
+ }
+ t.checked = true
+ }
+ nDst, n, err := utf8Decoder.Transform(utf8Decoder{}, dst[nDst:], src, atEOF)
+ nSrc += n
+ return nDst, nSrc, err
+}
+
+type utf8bomEncoder struct {
+ written bool
+ t transform.Transformer
+}
+
+func (t *utf8bomEncoder) Reset() {
+ t.written = false
+ t.t.Reset()
+}
+
+func (t *utf8bomEncoder) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) {
+ if !t.written {
+ if len(dst) < len(utf8BOM) {
+ return nDst, 0, transform.ErrShortDst
+ }
+ nDst = copy(dst, utf8BOM)
+ t.written = true
+ }
+ n, nSrc, err := utf8Decoder.Transform(utf8Decoder{}, dst[nDst:], src, atEOF)
+ nDst += n
+ return nDst, nSrc, err
+}
+
+type utf8Decoder struct{ transform.NopResetter }
+
+func (utf8Decoder) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) {
+ var pSrc int // point from which to start copy in src
+ var accept utf8internal.AcceptRange
+
+ // The decoder can only make the input larger, not smaller.
+ n := len(src)
+ if len(dst) < n {
+ err = transform.ErrShortDst
+ n = len(dst)
+ atEOF = false
+ }
+ for nSrc < n {
+ c := src[nSrc]
+ if c < utf8.RuneSelf {
+ nSrc++
+ continue
+ }
+ first := utf8internal.First[c]
+ size := int(first & utf8internal.SizeMask)
+ if first == utf8internal.FirstInvalid {
+ goto handleInvalid // invalid starter byte
+ }
+ accept = utf8internal.AcceptRanges[first>>utf8internal.AcceptShift]
+ if nSrc+size > n {
+ if !atEOF {
+ // We may stop earlier than necessary here if the short sequence
+ // has invalid bytes. Not checking for this simplifies the code
+ // and may avoid duplicate computations in certain conditions.
+ if err == nil {
+ err = transform.ErrShortSrc
+ }
+ break
+ }
+ // Determine the maximal subpart of an ill-formed subsequence.
+ switch {
+ case nSrc+1 >= n || src[nSrc+1] < accept.Lo || accept.Hi < src[nSrc+1]:
+ size = 1
+ case nSrc+2 >= n || src[nSrc+2] < utf8internal.LoCB || utf8internal.HiCB < src[nSrc+2]:
+ size = 2
+ default:
+ size = 3 // As we are short, the maximum is 3.
+ }
+ goto handleInvalid
+ }
+ if c = src[nSrc+1]; c < accept.Lo || accept.Hi < c {
+ size = 1
+ goto handleInvalid // invalid continuation byte
+ } else if size == 2 {
+ } else if c = src[nSrc+2]; c < utf8internal.LoCB || utf8internal.HiCB < c {
+ size = 2
+ goto handleInvalid // invalid continuation byte
+ } else if size == 3 {
+ } else if c = src[nSrc+3]; c < utf8internal.LoCB || utf8internal.HiCB < c {
+ size = 3
+ goto handleInvalid // invalid continuation byte
+ }
+ nSrc += size
+ continue
+
+ handleInvalid:
+ // Copy the scanned input so far.
+ nDst += copy(dst[nDst:], src[pSrc:nSrc])
+
+ // Append RuneError to the destination.
+ const runeError = "\ufffd"
+ if nDst+len(runeError) > len(dst) {
+ return nDst, nSrc, transform.ErrShortDst
+ }
+ nDst += copy(dst[nDst:], runeError)
+
+ // Skip the maximal subpart of an ill-formed subsequence according to
+ // the W3C standard way instead of the Go way. This Transform is
+ // probably the only place in the text repo where it is warranted.
+ nSrc += size
+ pSrc = nSrc
+
+ // Recompute the maximum source length.
+ if sz := len(dst) - nDst; sz < len(src)-nSrc {
+ err = transform.ErrShortDst
+ n = nSrc + sz
+ atEOF = false
+ }
+ }
+ return nDst + copy(dst[nDst:], src[pSrc:nSrc]), nSrc, err
+}
+
+// UTF16 returns a UTF-16 Encoding for the given default endianness and byte
+// order mark (BOM) policy.
+//
+// When decoding from UTF-16 to UTF-8, if the BOMPolicy is IgnoreBOM then
+// neither BOMs U+FEFF nor noncharacters U+FFFE in the input stream will affect
+// the endianness used for decoding, and will instead be output as their
+// standard UTF-8 encodings: "\xef\xbb\xbf" and "\xef\xbf\xbe". If the BOMPolicy
+// is UseBOM or ExpectBOM a staring BOM is not written to the UTF-8 output.
+// Instead, it overrides the default endianness e for the remainder of the
+// transformation. Any subsequent BOMs U+FEFF or noncharacters U+FFFE will not
+// affect the endianness used, and will instead be output as their standard
+// UTF-8 encodings. For UseBOM, if there is no starting BOM, it will proceed
+// with the default Endianness. For ExpectBOM, in that case, the transformation
+// will return early with an ErrMissingBOM error.
+//
+// When encoding from UTF-8 to UTF-16, a BOM will be inserted at the start of
+// the output if the BOMPolicy is UseBOM or ExpectBOM. Otherwise, a BOM will not
+// be inserted. The UTF-8 input does not need to contain a BOM.
+//
+// There is no concept of a 'native' endianness. If the UTF-16 data is produced
+// and consumed in a greater context that implies a certain endianness, use
+// IgnoreBOM. Otherwise, use ExpectBOM and always produce and consume a BOM.
+//
+// In the language of https://www.unicode.org/faq/utf_bom.html#bom10, IgnoreBOM
+// corresponds to "Where the precise type of the data stream is known... the
+// BOM should not be used" and ExpectBOM corresponds to "A particular
+// protocol... may require use of the BOM".
+func UTF16(e Endianness, b BOMPolicy) encoding.Encoding {
+ return utf16Encoding{config{e, b}, mibValue[e][b&bomMask]}
+}
+
+// mibValue maps Endianness and BOMPolicy settings to MIB constants. Note that
+// some configurations map to the same MIB identifier. RFC 2781 has requirements
+// and recommendations. Some of the "configurations" are merely recommendations,
+// so multiple configurations could match.
+var mibValue = map[Endianness][numBOMValues]identifier.MIB{
+ BigEndian: [numBOMValues]identifier.MIB{
+ IgnoreBOM: identifier.UTF16BE,
+ UseBOM: identifier.UTF16, // BigEnding default is preferred by RFC 2781.
+ // TODO: acceptBOM | strictBOM would map to UTF16BE as well.
+ },
+ LittleEndian: [numBOMValues]identifier.MIB{
+ IgnoreBOM: identifier.UTF16LE,
+ UseBOM: identifier.UTF16, // LittleEndian default is allowed and preferred on Windows.
+ // TODO: acceptBOM | strictBOM would map to UTF16LE as well.
+ },
+ // ExpectBOM is not widely used and has no valid MIB identifier.
+}
+
+// All lists a configuration for each IANA-defined UTF-16 variant.
+var All = []encoding.Encoding{
+ UTF8,
+ UTF16(BigEndian, UseBOM),
+ UTF16(BigEndian, IgnoreBOM),
+ UTF16(LittleEndian, IgnoreBOM),
+}
+
+// BOMPolicy is a UTF-16 encoding's byte order mark policy.
+type BOMPolicy uint8
+
+const (
+ writeBOM BOMPolicy = 0x01
+ acceptBOM BOMPolicy = 0x02
+ requireBOM BOMPolicy = 0x04
+ bomMask BOMPolicy = 0x07
+
+ // HACK: numBOMValues == 8 triggers a bug in the 1.4 compiler (cannot have a
+ // map of an array of length 8 of a type that is also used as a key or value
+ // in another map). See golang.org/issue/11354.
+ // TODO: consider changing this value back to 8 if the use of 1.4.* has
+ // been minimized.
+ numBOMValues = 8 + 1
+
+ // IgnoreBOM means to ignore any byte order marks.
+ IgnoreBOM BOMPolicy = 0
+ // Common and RFC 2781-compliant interpretation for UTF-16BE/LE.
+
+ // UseBOM means that the UTF-16 form may start with a byte order mark, which
+ // will be used to override the default encoding.
+ UseBOM BOMPolicy = writeBOM | acceptBOM
+ // Common and RFC 2781-compliant interpretation for UTF-16.
+
+ // ExpectBOM means that the UTF-16 form must start with a byte order mark,
+ // which will be used to override the default encoding.
+ ExpectBOM BOMPolicy = writeBOM | acceptBOM | requireBOM
+ // Used in Java as Unicode (not to be confused with Java's UTF-16) and
+ // ICU's UTF-16,version=1. Not compliant with RFC 2781.
+
+ // TODO (maybe): strictBOM: BOM must match Endianness. This would allow:
+ // - UTF-16(B|L)E,version=1: writeBOM | acceptBOM | requireBOM | strictBOM
+ // (UnicodeBig and UnicodeLittle in Java)
+ // - RFC 2781-compliant, but less common interpretation for UTF-16(B|L)E:
+ // acceptBOM | strictBOM (e.g. assigned to CheckBOM).
+ // This addition would be consistent with supporting ExpectBOM.
+)
+
+// Endianness is a UTF-16 encoding's default endianness.
+type Endianness bool
+
+const (
+ // BigEndian is UTF-16BE.
+ BigEndian Endianness = false
+ // LittleEndian is UTF-16LE.
+ LittleEndian Endianness = true
+)
+
+// ErrMissingBOM means that decoding UTF-16 input with ExpectBOM did not find a
+// starting byte order mark.
+var ErrMissingBOM = errors.New("encoding: missing byte order mark")
+
+type utf16Encoding struct {
+ config
+ mib identifier.MIB
+}
+
+type config struct {
+ endianness Endianness
+ bomPolicy BOMPolicy
+}
+
+func (u utf16Encoding) NewDecoder() *encoding.Decoder {
+ return &encoding.Decoder{Transformer: &utf16Decoder{
+ initial: u.config,
+ current: u.config,
+ }}
+}
+
+func (u utf16Encoding) NewEncoder() *encoding.Encoder {
+ return &encoding.Encoder{Transformer: &utf16Encoder{
+ endianness: u.endianness,
+ initialBOMPolicy: u.bomPolicy,
+ currentBOMPolicy: u.bomPolicy,
+ }}
+}
+
+func (u utf16Encoding) ID() (mib identifier.MIB, other string) {
+ return u.mib, ""
+}
+
+func (u utf16Encoding) String() string {
+ e, b := "B", ""
+ if u.endianness == LittleEndian {
+ e = "L"
+ }
+ switch u.bomPolicy {
+ case ExpectBOM:
+ b = "Expect"
+ case UseBOM:
+ b = "Use"
+ case IgnoreBOM:
+ b = "Ignore"
+ }
+ return "UTF-16" + e + "E (" + b + " BOM)"
+}
+
+type utf16Decoder struct {
+ initial config
+ current config
+}
+
+func (u *utf16Decoder) Reset() {
+ u.current = u.initial
+}
+
+func (u *utf16Decoder) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) {
+ if len(src) < 2 && atEOF && u.current.bomPolicy&requireBOM != 0 {
+ return 0, 0, ErrMissingBOM
+ }
+ if len(src) == 0 {
+ return 0, 0, nil
+ }
+ if len(src) >= 2 && u.current.bomPolicy&acceptBOM != 0 {
+ switch {
+ case src[0] == 0xfe && src[1] == 0xff:
+ u.current.endianness = BigEndian
+ nSrc = 2
+ case src[0] == 0xff && src[1] == 0xfe:
+ u.current.endianness = LittleEndian
+ nSrc = 2
+ default:
+ if u.current.bomPolicy&requireBOM != 0 {
+ return 0, 0, ErrMissingBOM
+ }
+ }
+ u.current.bomPolicy = IgnoreBOM
+ }
+
+ var r rune
+ var dSize, sSize int
+ for nSrc < len(src) {
+ if nSrc+1 < len(src) {
+ x := uint16(src[nSrc+0])<<8 | uint16(src[nSrc+1])
+ if u.current.endianness == LittleEndian {
+ x = x>>8 | x<<8
+ }
+ r, sSize = rune(x), 2
+ if utf16.IsSurrogate(r) {
+ if nSrc+3 < len(src) {
+ x = uint16(src[nSrc+2])<<8 | uint16(src[nSrc+3])
+ if u.current.endianness == LittleEndian {
+ x = x>>8 | x<<8
+ }
+ // Save for next iteration if it is not a high surrogate.
+ if isHighSurrogate(rune(x)) {
+ r, sSize = utf16.DecodeRune(r, rune(x)), 4
+ }
+ } else if !atEOF {
+ err = transform.ErrShortSrc
+ break
+ }
+ }
+ if dSize = utf8.RuneLen(r); dSize < 0 {
+ r, dSize = utf8.RuneError, 3
+ }
+ } else if atEOF {
+ // Single trailing byte.
+ r, dSize, sSize = utf8.RuneError, 3, 1
+ } else {
+ err = transform.ErrShortSrc
+ break
+ }
+ if nDst+dSize > len(dst) {
+ err = transform.ErrShortDst
+ break
+ }
+ nDst += utf8.EncodeRune(dst[nDst:], r)
+ nSrc += sSize
+ }
+ return nDst, nSrc, err
+}
+
+func isHighSurrogate(r rune) bool {
+ return 0xDC00 <= r && r <= 0xDFFF
+}
+
+type utf16Encoder struct {
+ endianness Endianness
+ initialBOMPolicy BOMPolicy
+ currentBOMPolicy BOMPolicy
+}
+
+func (u *utf16Encoder) Reset() {
+ u.currentBOMPolicy = u.initialBOMPolicy
+}
+
+func (u *utf16Encoder) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) {
+ if u.currentBOMPolicy&writeBOM != 0 {
+ if len(dst) < 2 {
+ return 0, 0, transform.ErrShortDst
+ }
+ dst[0], dst[1] = 0xfe, 0xff
+ u.currentBOMPolicy = IgnoreBOM
+ nDst = 2
+ }
+
+ r, size := rune(0), 0
+ for nSrc < len(src) {
+ r = rune(src[nSrc])
+
+ // Decode a 1-byte rune.
+ if r < utf8.RuneSelf {
+ size = 1
+
+ } else {
+ // Decode a multi-byte rune.
+ r, size = utf8.DecodeRune(src[nSrc:])
+ if size == 1 {
+ // All valid runes of size 1 (those below utf8.RuneSelf) were
+ // handled above. We have invalid UTF-8 or we haven't seen the
+ // full character yet.
+ if !atEOF && !utf8.FullRune(src[nSrc:]) {
+ err = transform.ErrShortSrc
+ break
+ }
+ }
+ }
+
+ if r <= 0xffff {
+ if nDst+2 > len(dst) {
+ err = transform.ErrShortDst
+ break
+ }
+ dst[nDst+0] = uint8(r >> 8)
+ dst[nDst+1] = uint8(r)
+ nDst += 2
+ } else {
+ if nDst+4 > len(dst) {
+ err = transform.ErrShortDst
+ break
+ }
+ r1, r2 := utf16.EncodeRune(r)
+ dst[nDst+0] = uint8(r1 >> 8)
+ dst[nDst+1] = uint8(r1)
+ dst[nDst+2] = uint8(r2 >> 8)
+ dst[nDst+3] = uint8(r2)
+ nDst += 4
+ }
+ nSrc += size
+ }
+
+ if u.endianness == LittleEndian {
+ for i := 0; i < nDst; i += 2 {
+ dst[i], dst[i+1] = dst[i+1], dst[i]
+ }
+ }
+ return nDst, nSrc, err
+}
diff --git a/vendor/golang.org/x/text/internal/utf8internal/utf8internal.go b/vendor/golang.org/x/text/internal/utf8internal/utf8internal.go
new file mode 100644
index 000000000..e5c53b1b3
--- /dev/null
+++ b/vendor/golang.org/x/text/internal/utf8internal/utf8internal.go
@@ -0,0 +1,87 @@
+// Copyright 2015 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.
+
+// Package utf8internal contains low-level utf8-related constants, tables, etc.
+// that are used internally by the text package.
+package utf8internal
+
+// The default lowest and highest continuation byte.
+const (
+ LoCB = 0x80 // 1000 0000
+ HiCB = 0xBF // 1011 1111
+)
+
+// Constants related to getting information of first bytes of UTF-8 sequences.
+const (
+ // ASCII identifies a UTF-8 byte as ASCII.
+ ASCII = as
+
+ // FirstInvalid indicates a byte is invalid as a first byte of a UTF-8
+ // sequence.
+ FirstInvalid = xx
+
+ // SizeMask is a mask for the size bits. Use use x&SizeMask to get the size.
+ SizeMask = 7
+
+ // AcceptShift is the right-shift count for the first byte info byte to get
+ // the index into the AcceptRanges table. See AcceptRanges.
+ AcceptShift = 4
+
+ // The names of these constants are chosen to give nice alignment in the
+ // table below. The first nibble is an index into acceptRanges or F for
+ // special one-byte cases. The second nibble is the Rune length or the
+ // Status for the special one-byte case.
+ xx = 0xF1 // invalid: size 1
+ as = 0xF0 // ASCII: size 1
+ s1 = 0x02 // accept 0, size 2
+ s2 = 0x13 // accept 1, size 3
+ s3 = 0x03 // accept 0, size 3
+ s4 = 0x23 // accept 2, size 3
+ s5 = 0x34 // accept 3, size 4
+ s6 = 0x04 // accept 0, size 4
+ s7 = 0x44 // accept 4, size 4
+)
+
+// First is information about the first byte in a UTF-8 sequence.
+var First = [256]uint8{
+ // 1 2 3 4 5 6 7 8 9 A B C D E F
+ as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, // 0x00-0x0F
+ as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, // 0x10-0x1F
+ as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, // 0x20-0x2F
+ as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, // 0x30-0x3F
+ as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, // 0x40-0x4F
+ as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, // 0x50-0x5F
+ as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, // 0x60-0x6F
+ as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, // 0x70-0x7F
+ // 1 2 3 4 5 6 7 8 9 A B C D E F
+ xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, // 0x80-0x8F
+ xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, // 0x90-0x9F
+ xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, // 0xA0-0xAF
+ xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, // 0xB0-0xBF
+ xx, xx, s1, s1, s1, s1, s1, s1, s1, s1, s1, s1, s1, s1, s1, s1, // 0xC0-0xCF
+ s1, s1, s1, s1, s1, s1, s1, s1, s1, s1, s1, s1, s1, s1, s1, s1, // 0xD0-0xDF
+ s2, s3, s3, s3, s3, s3, s3, s3, s3, s3, s3, s3, s3, s4, s3, s3, // 0xE0-0xEF
+ s5, s6, s6, s6, s7, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, // 0xF0-0xFF
+}
+
+// AcceptRange gives the range of valid values for the second byte in a UTF-8
+// sequence for any value for First that is not ASCII or FirstInvalid.
+type AcceptRange struct {
+ Lo uint8 // lowest value for second byte.
+ Hi uint8 // highest value for second byte.
+}
+
+// AcceptRanges is a slice of AcceptRange values. For a given byte sequence b
+//
+// AcceptRanges[First[b[0]]>>AcceptShift]
+//
+// will give the value of AcceptRange for the multi-byte UTF-8 sequence starting
+// at b[0].
+var AcceptRanges = [...]AcceptRange{
+ 0: {LoCB, HiCB},
+ 1: {0xA0, HiCB},
+ 2: {LoCB, 0x9F},
+ 3: {0x90, HiCB},
+ 4: {LoCB, 0x8F},
+}
diff --git a/vendor/golang.org/x/tools/go/internal/packagesdriver/sizes.go b/vendor/golang.org/x/tools/go/internal/packagesdriver/sizes.go
index 0454cdd78..333676b7c 100644
--- a/vendor/golang.org/x/tools/go/internal/packagesdriver/sizes.go
+++ b/vendor/golang.org/x/tools/go/internal/packagesdriver/sizes.go
@@ -13,16 +13,17 @@ import (
"golang.org/x/tools/internal/gocommand"
)
-var debug = false
-
func GetSizesForArgsGolist(ctx context.Context, inv gocommand.Invocation, gocmdRunner *gocommand.Runner) (string, string, error) {
inv.Verb = "list"
inv.Args = []string{"-f", "{{context.GOARCH}} {{context.Compiler}}", "--", "unsafe"}
stdout, stderr, friendlyErr, rawErr := gocmdRunner.RunRaw(ctx, inv)
var goarch, compiler string
if rawErr != nil {
- if rawErrMsg := rawErr.Error(); strings.Contains(rawErrMsg, "cannot find main module") || strings.Contains(rawErrMsg, "go.mod file not found") {
- // User's running outside of a module. All bets are off. Get GOARCH and guess compiler is gc.
+ rawErrMsg := rawErr.Error()
+ if strings.Contains(rawErrMsg, "cannot find main module") ||
+ strings.Contains(rawErrMsg, "go.mod file not found") {
+ // User's running outside of a module.
+ // All bets are off. Get GOARCH and guess compiler is gc.
// TODO(matloob): Is this a problem in practice?
inv.Verb = "env"
inv.Args = []string{"GOARCH"}
@@ -32,8 +33,12 @@ func GetSizesForArgsGolist(ctx context.Context, inv gocommand.Invocation, gocmdR
}
goarch = strings.TrimSpace(envout.String())
compiler = "gc"
- } else {
+ } else if friendlyErr != nil {
return "", "", friendlyErr
+ } else {
+ // This should be unreachable, but be defensive
+ // in case RunRaw's error results are inconsistent.
+ return "", "", rawErr
}
} else {
fields := strings.Fields(stdout.String())
diff --git a/vendor/golang.org/x/tools/go/packages/doc.go b/vendor/golang.org/x/tools/go/packages/doc.go
index da4ab89fe..b2a0b7c6a 100644
--- a/vendor/golang.org/x/tools/go/packages/doc.go
+++ b/vendor/golang.org/x/tools/go/packages/doc.go
@@ -5,12 +5,32 @@
/*
Package packages loads Go packages for inspection and analysis.
-The Load function takes as input a list of patterns and return a list of Package
-structs describing individual packages matched by those patterns.
-The LoadMode controls the amount of detail in the loaded packages.
+The [Load] function takes as input a list of patterns and returns a
+list of [Package] values describing individual packages matched by those
+patterns.
+A [Config] specifies configuration options, the most important of which is
+the [LoadMode], which controls the amount of detail in the loaded packages.
-Load passes most patterns directly to the underlying build tool,
-but all patterns with the prefix "query=", where query is a
+Load passes most patterns directly to the underlying build tool.
+The default build tool is the go command.
+Its supported patterns are described at
+https://pkg.go.dev/cmd/go#hdr-Package_lists_and_patterns.
+
+Load may be used in Go projects that use alternative build systems, by
+installing an appropriate "driver" program for the build system and
+specifying its location in the GOPACKAGESDRIVER environment variable.
+For example,
+https://github.com/bazelbuild/rules_go/wiki/Editor-and-tool-integration
+explains how to use the driver for Bazel.
+The driver program is responsible for interpreting patterns in its
+preferred notation and reporting information about the packages that
+they identify.
+(See driverRequest and driverResponse types for the JSON
+schema used by the protocol.
+Though the protocol is supported, these types are currently unexported;
+see #64608 for a proposal to publish them.)
+
+Regardless of driver, all patterns with the prefix "query=", where query is a
non-empty string of letters from [a-z], are reserved and may be
interpreted as query operators.
@@ -35,7 +55,7 @@ The Package struct provides basic information about the package, including
- Imports, a map from source import strings to the Packages they name;
- Types, the type information for the package's exported symbols;
- Syntax, the parsed syntax trees for the package's source code; and
- - TypeInfo, the result of a complete type-check of the package syntax trees.
+ - TypesInfo, the result of a complete type-check of the package syntax trees.
(See the documentation for type Package for the complete list of fields
and more detailed descriptions.)
@@ -64,7 +84,7 @@ reported about the loaded packages. See the documentation for type LoadMode
for details.
Most tools should pass their command-line arguments (after any flags)
-uninterpreted to the loader, so that the loader can interpret them
+uninterpreted to [Load], so that it can interpret them
according to the conventions of the underlying build system.
See the Example function for typical usage.
*/
diff --git a/vendor/golang.org/x/tools/go/packages/external.go b/vendor/golang.org/x/tools/go/packages/external.go
index 7242a0a7d..7db1d1293 100644
--- a/vendor/golang.org/x/tools/go/packages/external.go
+++ b/vendor/golang.org/x/tools/go/packages/external.go
@@ -12,8 +12,8 @@ import (
"bytes"
"encoding/json"
"fmt"
- exec "golang.org/x/sys/execabs"
"os"
+ "os/exec"
"strings"
)
diff --git a/vendor/golang.org/x/tools/go/packages/golist.go b/vendor/golang.org/x/tools/go/packages/golist.go
index b5de9cf9f..cd375fbc3 100644
--- a/vendor/golang.org/x/tools/go/packages/golist.go
+++ b/vendor/golang.org/x/tools/go/packages/golist.go
@@ -9,9 +9,9 @@ import (
"context"
"encoding/json"
"fmt"
- "io/ioutil"
"log"
"os"
+ "os/exec"
"path"
"path/filepath"
"reflect"
@@ -21,7 +21,6 @@ import (
"sync"
"unicode"
- exec "golang.org/x/sys/execabs"
"golang.org/x/tools/go/internal/packagesdriver"
"golang.org/x/tools/internal/gocommand"
"golang.org/x/tools/internal/packagesinternal"
@@ -209,62 +208,6 @@ extractQueries:
}
}
- // Only use go/packages' overlay processing if we're using a Go version
- // below 1.16. Otherwise, go list handles it.
- if goVersion, err := state.getGoVersion(); err == nil && goVersion < 16 {
- modifiedPkgs, needPkgs, err := state.processGolistOverlay(response)
- if err != nil {
- return nil, err
- }
-
- var containsCandidates []string
- if len(containFiles) > 0 {
- containsCandidates = append(containsCandidates, modifiedPkgs...)
- containsCandidates = append(containsCandidates, needPkgs...)
- }
- if err := state.addNeededOverlayPackages(response, needPkgs); err != nil {
- return nil, err
- }
- // Check candidate packages for containFiles.
- if len(containFiles) > 0 {
- for _, id := range containsCandidates {
- pkg, ok := response.seenPackages[id]
- if !ok {
- response.addPackage(&Package{
- ID: id,
- Errors: []Error{{
- Kind: ListError,
- Msg: fmt.Sprintf("package %s expected but not seen", id),
- }},
- })
- continue
- }
- for _, f := range containFiles {
- for _, g := range pkg.GoFiles {
- if sameFile(f, g) {
- response.addRoot(id)
- }
- }
- }
- }
- }
- // Add root for any package that matches a pattern. This applies only to
- // packages that are modified by overlays, since they are not added as
- // roots automatically.
- for _, pattern := range restPatterns {
- match := matchPattern(pattern)
- for _, pkgID := range modifiedPkgs {
- pkg, ok := response.seenPackages[pkgID]
- if !ok {
- continue
- }
- if match(pkg.PkgPath) {
- response.addRoot(pkg.ID)
- }
- }
- }
- }
-
sizeswg.Wait()
if sizeserr != nil {
return nil, sizeserr
@@ -272,24 +215,6 @@ extractQueries:
return response.dr, nil
}
-func (state *golistState) addNeededOverlayPackages(response *responseDeduper, pkgs []string) error {
- if len(pkgs) == 0 {
- return nil
- }
- dr, err := state.createDriverResponse(pkgs...)
- if err != nil {
- return err
- }
- for _, pkg := range dr.Packages {
- response.addPackage(pkg)
- }
- _, needPkgs, err := state.processGolistOverlay(response)
- if err != nil {
- return err
- }
- return state.addNeededOverlayPackages(response, needPkgs)
-}
-
func (state *golistState) runContainsQueries(response *responseDeduper, queries []string) error {
for _, query := range queries {
// TODO(matloob): Do only one query per directory.
@@ -1109,7 +1034,7 @@ func (state *golistState) writeOverlays() (filename string, cleanup func(), err
if len(state.cfg.Overlay) == 0 {
return "", func() {}, nil
}
- dir, err := ioutil.TempDir("", "gopackages-*")
+ dir, err := os.MkdirTemp("", "gopackages-*")
if err != nil {
return "", nil, err
}
@@ -1128,7 +1053,7 @@ func (state *golistState) writeOverlays() (filename string, cleanup func(), err
// Create a unique filename for the overlaid files, to avoid
// creating nested directories.
noSeparator := strings.Join(strings.Split(filepath.ToSlash(k), "/"), "")
- f, err := ioutil.TempFile(dir, fmt.Sprintf("*-%s", noSeparator))
+ f, err := os.CreateTemp(dir, fmt.Sprintf("*-%s", noSeparator))
if err != nil {
return "", func() {}, err
}
@@ -1146,7 +1071,7 @@ func (state *golistState) writeOverlays() (filename string, cleanup func(), err
}
// Write out the overlay file that contains the filepath mappings.
filename = filepath.Join(dir, "overlay.json")
- if err := ioutil.WriteFile(filename, b, 0665); err != nil {
+ if err := os.WriteFile(filename, b, 0665); err != nil {
return "", func() {}, err
}
return filename, cleanup, nil
diff --git a/vendor/golang.org/x/tools/go/packages/golist_overlay.go b/vendor/golang.org/x/tools/go/packages/golist_overlay.go
index 9576b472f..d823c474a 100644
--- a/vendor/golang.org/x/tools/go/packages/golist_overlay.go
+++ b/vendor/golang.org/x/tools/go/packages/golist_overlay.go
@@ -6,314 +6,11 @@ package packages
import (
"encoding/json"
- "fmt"
- "go/parser"
- "go/token"
- "os"
"path/filepath"
- "regexp"
- "sort"
- "strconv"
- "strings"
"golang.org/x/tools/internal/gocommand"
)
-// processGolistOverlay provides rudimentary support for adding
-// files that don't exist on disk to an overlay. The results can be
-// sometimes incorrect.
-// TODO(matloob): Handle unsupported cases, including the following:
-// - determining the correct package to add given a new import path
-func (state *golistState) processGolistOverlay(response *responseDeduper) (modifiedPkgs, needPkgs []string, err error) {
- havePkgs := make(map[string]string) // importPath -> non-test package ID
- needPkgsSet := make(map[string]bool)
- modifiedPkgsSet := make(map[string]bool)
-
- pkgOfDir := make(map[string][]*Package)
- for _, pkg := range response.dr.Packages {
- // This is an approximation of import path to id. This can be
- // wrong for tests, vendored packages, and a number of other cases.
- havePkgs[pkg.PkgPath] = pkg.ID
- dir, err := commonDir(pkg.GoFiles)
- if err != nil {
- return nil, nil, err
- }
- if dir != "" {
- pkgOfDir[dir] = append(pkgOfDir[dir], pkg)
- }
- }
-
- // If no new imports are added, it is safe to avoid loading any needPkgs.
- // Otherwise, it's hard to tell which package is actually being loaded
- // (due to vendoring) and whether any modified package will show up
- // in the transitive set of dependencies (because new imports are added,
- // potentially modifying the transitive set of dependencies).
- var overlayAddsImports bool
-
- // If both a package and its test package are created by the overlay, we
- // need the real package first. Process all non-test files before test
- // files, and make the whole process deterministic while we're at it.
- var overlayFiles []string
- for opath := range state.cfg.Overlay {
- overlayFiles = append(overlayFiles, opath)
- }
- sort.Slice(overlayFiles, func(i, j int) bool {
- iTest := strings.HasSuffix(overlayFiles[i], "_test.go")
- jTest := strings.HasSuffix(overlayFiles[j], "_test.go")
- if iTest != jTest {
- return !iTest // non-tests are before tests.
- }
- return overlayFiles[i] < overlayFiles[j]
- })
- for _, opath := range overlayFiles {
- contents := state.cfg.Overlay[opath]
- base := filepath.Base(opath)
- dir := filepath.Dir(opath)
- var pkg *Package // if opath belongs to both a package and its test variant, this will be the test variant
- var testVariantOf *Package // if opath is a test file, this is the package it is testing
- var fileExists bool
- isTestFile := strings.HasSuffix(opath, "_test.go")
- pkgName, ok := extractPackageName(opath, contents)
- if !ok {
- // Don't bother adding a file that doesn't even have a parsable package statement
- // to the overlay.
- continue
- }
- // If all the overlay files belong to a different package, change the
- // package name to that package.
- maybeFixPackageName(pkgName, isTestFile, pkgOfDir[dir])
- nextPackage:
- for _, p := range response.dr.Packages {
- if pkgName != p.Name && p.ID != "command-line-arguments" {
- continue
- }
- for _, f := range p.GoFiles {
- if !sameFile(filepath.Dir(f), dir) {
- continue
- }
- // Make sure to capture information on the package's test variant, if needed.
- if isTestFile && !hasTestFiles(p) {
- // TODO(matloob): Are there packages other than the 'production' variant
- // of a package that this can match? This shouldn't match the test main package
- // because the file is generated in another directory.
- testVariantOf = p
- continue nextPackage
- } else if !isTestFile && hasTestFiles(p) {
- // We're examining a test variant, but the overlaid file is
- // a non-test file. Because the overlay implementation
- // (currently) only adds a file to one package, skip this
- // package, so that we can add the file to the production
- // variant of the package. (https://golang.org/issue/36857
- // tracks handling overlays on both the production and test
- // variant of a package).
- continue nextPackage
- }
- if pkg != nil && p != pkg && pkg.PkgPath == p.PkgPath {
- // We have already seen the production version of the
- // for which p is a test variant.
- if hasTestFiles(p) {
- testVariantOf = pkg
- }
- }
- pkg = p
- if filepath.Base(f) == base {
- fileExists = true
- }
- }
- }
- // The overlay could have included an entirely new package or an
- // ad-hoc package. An ad-hoc package is one that we have manually
- // constructed from inadequate `go list` results for a file= query.
- // It will have the ID command-line-arguments.
- if pkg == nil || pkg.ID == "command-line-arguments" {
- // Try to find the module or gopath dir the file is contained in.
- // Then for modules, add the module opath to the beginning.
- pkgPath, ok, err := state.getPkgPath(dir)
- if err != nil {
- return nil, nil, err
- }
- if !ok {
- break
- }
- var forTest string // only set for x tests
- isXTest := strings.HasSuffix(pkgName, "_test")
- if isXTest {
- forTest = pkgPath
- pkgPath += "_test"
- }
- id := pkgPath
- if isTestFile {
- if isXTest {
- id = fmt.Sprintf("%s [%s.test]", pkgPath, forTest)
- } else {
- id = fmt.Sprintf("%s [%s.test]", pkgPath, pkgPath)
- }
- }
- if pkg != nil {
- // TODO(rstambler): We should change the package's path and ID
- // here. The only issue is that this messes with the roots.
- } else {
- // Try to reclaim a package with the same ID, if it exists in the response.
- for _, p := range response.dr.Packages {
- if reclaimPackage(p, id, opath, contents) {
- pkg = p
- break
- }
- }
- // Otherwise, create a new package.
- if pkg == nil {
- pkg = &Package{
- PkgPath: pkgPath,
- ID: id,
- Name: pkgName,
- Imports: make(map[string]*Package),
- }
- response.addPackage(pkg)
- havePkgs[pkg.PkgPath] = id
- // Add the production package's sources for a test variant.
- if isTestFile && !isXTest && testVariantOf != nil {
- pkg.GoFiles = append(pkg.GoFiles, testVariantOf.GoFiles...)
- pkg.CompiledGoFiles = append(pkg.CompiledGoFiles, testVariantOf.CompiledGoFiles...)
- // Add the package under test and its imports to the test variant.
- pkg.forTest = testVariantOf.PkgPath
- for k, v := range testVariantOf.Imports {
- pkg.Imports[k] = &Package{ID: v.ID}
- }
- }
- if isXTest {
- pkg.forTest = forTest
- }
- }
- }
- }
- if !fileExists {
- pkg.GoFiles = append(pkg.GoFiles, opath)
- // TODO(matloob): Adding the file to CompiledGoFiles can exhibit the wrong behavior
- // if the file will be ignored due to its build tags.
- pkg.CompiledGoFiles = append(pkg.CompiledGoFiles, opath)
- modifiedPkgsSet[pkg.ID] = true
- }
- imports, err := extractImports(opath, contents)
- if err != nil {
- // Let the parser or type checker report errors later.
- continue
- }
- for _, imp := range imports {
- // TODO(rstambler): If the package is an x test and the import has
- // a test variant, make sure to replace it.
- if _, found := pkg.Imports[imp]; found {
- continue
- }
- overlayAddsImports = true
- id, ok := havePkgs[imp]
- if !ok {
- var err error
- id, err = state.resolveImport(dir, imp)
- if err != nil {
- return nil, nil, err
- }
- }
- pkg.Imports[imp] = &Package{ID: id}
- // Add dependencies to the non-test variant version of this package as well.
- if testVariantOf != nil {
- testVariantOf.Imports[imp] = &Package{ID: id}
- }
- }
- }
-
- // toPkgPath guesses the package path given the id.
- toPkgPath := func(sourceDir, id string) (string, error) {
- if i := strings.IndexByte(id, ' '); i >= 0 {
- return state.resolveImport(sourceDir, id[:i])
- }
- return state.resolveImport(sourceDir, id)
- }
-
- // Now that new packages have been created, do another pass to determine
- // the new set of missing packages.
- for _, pkg := range response.dr.Packages {
- for _, imp := range pkg.Imports {
- if len(pkg.GoFiles) == 0 {
- return nil, nil, fmt.Errorf("cannot resolve imports for package %q with no Go files", pkg.PkgPath)
- }
- pkgPath, err := toPkgPath(filepath.Dir(pkg.GoFiles[0]), imp.ID)
- if err != nil {
- return nil, nil, err
- }
- if _, ok := havePkgs[pkgPath]; !ok {
- needPkgsSet[pkgPath] = true
- }
- }
- }
-
- if overlayAddsImports {
- needPkgs = make([]string, 0, len(needPkgsSet))
- for pkg := range needPkgsSet {
- needPkgs = append(needPkgs, pkg)
- }
- }
- modifiedPkgs = make([]string, 0, len(modifiedPkgsSet))
- for pkg := range modifiedPkgsSet {
- modifiedPkgs = append(modifiedPkgs, pkg)
- }
- return modifiedPkgs, needPkgs, err
-}
-
-// resolveImport finds the ID of a package given its import path.
-// In particular, it will find the right vendored copy when in GOPATH mode.
-func (state *golistState) resolveImport(sourceDir, importPath string) (string, error) {
- env, err := state.getEnv()
- if err != nil {
- return "", err
- }
- if env["GOMOD"] != "" {
- return importPath, nil
- }
-
- searchDir := sourceDir
- for {
- vendorDir := filepath.Join(searchDir, "vendor")
- exists, ok := state.vendorDirs[vendorDir]
- if !ok {
- info, err := os.Stat(vendorDir)
- exists = err == nil && info.IsDir()
- state.vendorDirs[vendorDir] = exists
- }
-
- if exists {
- vendoredPath := filepath.Join(vendorDir, importPath)
- if info, err := os.Stat(vendoredPath); err == nil && info.IsDir() {
- // We should probably check for .go files here, but shame on anyone who fools us.
- path, ok, err := state.getPkgPath(vendoredPath)
- if err != nil {
- return "", err
- }
- if ok {
- return path, nil
- }
- }
- }
-
- // We know we've hit the top of the filesystem when we Dir / and get /,
- // or C:\ and get C:\, etc.
- next := filepath.Dir(searchDir)
- if next == searchDir {
- break
- }
- searchDir = next
- }
- return importPath, nil
-}
-
-func hasTestFiles(p *Package) bool {
- for _, f := range p.GoFiles {
- if strings.HasSuffix(f, "_test.go") {
- return true
- }
- }
- return false
-}
-
// determineRootDirs returns a mapping from absolute directories that could
// contain code to their corresponding import path prefixes.
func (state *golistState) determineRootDirs() (map[string]string, error) {
@@ -384,192 +81,3 @@ func (state *golistState) determineRootDirsGOPATH() (map[string]string, error) {
}
return m, nil
}
-
-func extractImports(filename string, contents []byte) ([]string, error) {
- f, err := parser.ParseFile(token.NewFileSet(), filename, contents, parser.ImportsOnly) // TODO(matloob): reuse fileset?
- if err != nil {
- return nil, err
- }
- var res []string
- for _, imp := range f.Imports {
- quotedPath := imp.Path.Value
- path, err := strconv.Unquote(quotedPath)
- if err != nil {
- return nil, err
- }
- res = append(res, path)
- }
- return res, nil
-}
-
-// reclaimPackage attempts to reuse a package that failed to load in an overlay.
-//
-// If the package has errors and has no Name, GoFiles, or Imports,
-// then it's possible that it doesn't yet exist on disk.
-func reclaimPackage(pkg *Package, id string, filename string, contents []byte) bool {
- // TODO(rstambler): Check the message of the actual error?
- // It differs between $GOPATH and module mode.
- if pkg.ID != id {
- return false
- }
- if len(pkg.Errors) != 1 {
- return false
- }
- if pkg.Name != "" || pkg.ExportFile != "" {
- return false
- }
- if len(pkg.GoFiles) > 0 || len(pkg.CompiledGoFiles) > 0 || len(pkg.OtherFiles) > 0 {
- return false
- }
- if len(pkg.Imports) > 0 {
- return false
- }
- pkgName, ok := extractPackageName(filename, contents)
- if !ok {
- return false
- }
- pkg.Name = pkgName
- pkg.Errors = nil
- return true
-}
-
-func extractPackageName(filename string, contents []byte) (string, bool) {
- // TODO(rstambler): Check the message of the actual error?
- // It differs between $GOPATH and module mode.
- f, err := parser.ParseFile(token.NewFileSet(), filename, contents, parser.PackageClauseOnly) // TODO(matloob): reuse fileset?
- if err != nil {
- return "", false
- }
- return f.Name.Name, true
-}
-
-// commonDir returns the directory that all files are in, "" if files is empty,
-// or an error if they aren't in the same directory.
-func commonDir(files []string) (string, error) {
- seen := make(map[string]bool)
- for _, f := range files {
- seen[filepath.Dir(f)] = true
- }
- if len(seen) > 1 {
- return "", fmt.Errorf("files (%v) are in more than one directory: %v", files, seen)
- }
- for k := range seen {
- // seen has only one element; return it.
- return k, nil
- }
- return "", nil // no files
-}
-
-// It is possible that the files in the disk directory dir have a different package
-// name from newName, which is deduced from the overlays. If they all have a different
-// package name, and they all have the same package name, then that name becomes
-// the package name.
-// It returns true if it changes the package name, false otherwise.
-func maybeFixPackageName(newName string, isTestFile bool, pkgsOfDir []*Package) {
- names := make(map[string]int)
- for _, p := range pkgsOfDir {
- names[p.Name]++
- }
- if len(names) != 1 {
- // some files are in different packages
- return
- }
- var oldName string
- for k := range names {
- oldName = k
- }
- if newName == oldName {
- return
- }
- // We might have a case where all of the package names in the directory are
- // the same, but the overlay file is for an x test, which belongs to its
- // own package. If the x test does not yet exist on disk, we may not yet
- // have its package name on disk, but we should not rename the packages.
- //
- // We use a heuristic to determine if this file belongs to an x test:
- // The test file should have a package name whose package name has a _test
- // suffix or looks like "newName_test".
- maybeXTest := strings.HasPrefix(oldName+"_test", newName) || strings.HasSuffix(newName, "_test")
- if isTestFile && maybeXTest {
- return
- }
- for _, p := range pkgsOfDir {
- p.Name = newName
- }
-}
-
-// This function is copy-pasted from
-// https://github.com/golang/go/blob/9706f510a5e2754595d716bd64be8375997311fb/src/cmd/go/internal/search/search.go#L360.
-// It should be deleted when we remove support for overlays from go/packages.
-//
-// NOTE: This does not handle any ./... or ./ style queries, as this function
-// doesn't know the working directory.
-//
-// matchPattern(pattern)(name) reports whether
-// name matches pattern. Pattern is a limited glob
-// pattern in which '...' means 'any string' and there
-// is no other special syntax.
-// Unfortunately, there are two special cases. Quoting "go help packages":
-//
-// First, /... at the end of the pattern can match an empty string,
-// so that net/... matches both net and packages in its subdirectories, like net/http.
-// Second, any slash-separated pattern element containing a wildcard never
-// participates in a match of the "vendor" element in the path of a vendored
-// package, so that ./... does not match packages in subdirectories of
-// ./vendor or ./mycode/vendor, but ./vendor/... and ./mycode/vendor/... do.
-// Note, however, that a directory named vendor that itself contains code
-// is not a vendored package: cmd/vendor would be a command named vendor,
-// and the pattern cmd/... matches it.
-func matchPattern(pattern string) func(name string) bool {
- // Convert pattern to regular expression.
- // The strategy for the trailing /... is to nest it in an explicit ? expression.
- // The strategy for the vendor exclusion is to change the unmatchable
- // vendor strings to a disallowed code point (vendorChar) and to use
- // "(anything but that codepoint)*" as the implementation of the ... wildcard.
- // This is a bit complicated but the obvious alternative,
- // namely a hand-written search like in most shell glob matchers,
- // is too easy to make accidentally exponential.
- // Using package regexp guarantees linear-time matching.
-
- const vendorChar = "\x00"
-
- if strings.Contains(pattern, vendorChar) {
- return func(name string) bool { return false }
- }
-
- re := regexp.QuoteMeta(pattern)
- re = replaceVendor(re, vendorChar)
- switch {
- case strings.HasSuffix(re, `/`+vendorChar+`/\.\.\.`):
- re = strings.TrimSuffix(re, `/`+vendorChar+`/\.\.\.`) + `(/vendor|/` + vendorChar + `/\.\.\.)`
- case re == vendorChar+`/\.\.\.`:
- re = `(/vendor|/` + vendorChar + `/\.\.\.)`
- case strings.HasSuffix(re, `/\.\.\.`):
- re = strings.TrimSuffix(re, `/\.\.\.`) + `(/\.\.\.)?`
- }
- re = strings.ReplaceAll(re, `\.\.\.`, `[^`+vendorChar+`]*`)
-
- reg := regexp.MustCompile(`^` + re + `$`)
-
- return func(name string) bool {
- if strings.Contains(name, vendorChar) {
- return false
- }
- return reg.MatchString(replaceVendor(name, vendorChar))
- }
-}
-
-// replaceVendor returns the result of replacing
-// non-trailing vendor path elements in x with repl.
-func replaceVendor(x, repl string) string {
- if !strings.Contains(x, "vendor") {
- return x
- }
- elem := strings.Split(x, "/")
- for i := 0; i < len(elem)-1; i++ {
- if elem[i] == "vendor" {
- elem[i] = repl
- }
- }
- return strings.Join(elem, "/")
-}
diff --git a/vendor/golang.org/x/tools/go/packages/packages.go b/vendor/golang.org/x/tools/go/packages/packages.go
index 124a6fe14..81e9e6a72 100644
--- a/vendor/golang.org/x/tools/go/packages/packages.go
+++ b/vendor/golang.org/x/tools/go/packages/packages.go
@@ -16,7 +16,6 @@ import (
"go/token"
"go/types"
"io"
- "io/ioutil"
"log"
"os"
"path/filepath"
@@ -28,8 +27,8 @@ import (
"golang.org/x/tools/go/gcexportdata"
"golang.org/x/tools/internal/gocommand"
"golang.org/x/tools/internal/packagesinternal"
- "golang.org/x/tools/internal/typeparams"
"golang.org/x/tools/internal/typesinternal"
+ "golang.org/x/tools/internal/versions"
)
// A LoadMode controls the amount of detail to return when loading.
@@ -259,31 +258,52 @@ type driverResponse struct {
// proceeding with further analysis. The PrintErrors function is
// provided for convenient display of all errors.
func Load(cfg *Config, patterns ...string) ([]*Package, error) {
- l := newLoader(cfg)
- response, err := defaultDriver(&l.Config, patterns...)
+ ld := newLoader(cfg)
+ response, external, err := defaultDriver(&ld.Config, patterns...)
if err != nil {
return nil, err
}
- l.sizes = types.SizesFor(response.Compiler, response.Arch)
- return l.refine(response)
+
+ ld.sizes = types.SizesFor(response.Compiler, response.Arch)
+ if ld.sizes == nil && ld.Config.Mode&(NeedTypes|NeedTypesSizes|NeedTypesInfo) != 0 {
+ // Type size information is needed but unavailable.
+ if external {
+ // An external driver may fail to populate the Compiler/GOARCH fields,
+ // especially since they are relatively new (see #63700).
+ // Provide a sensible fallback in this case.
+ ld.sizes = types.SizesFor("gc", runtime.GOARCH)
+ if ld.sizes == nil { // gccgo-only arch
+ ld.sizes = types.SizesFor("gc", "amd64")
+ }
+ } else {
+ // Go list should never fail to deliver accurate size information.
+ // Reject the whole Load since the error is the same for every package.
+ return nil, fmt.Errorf("can't determine type sizes for compiler %q on GOARCH %q",
+ response.Compiler, response.Arch)
+ }
+ }
+
+ return ld.refine(response)
}
// defaultDriver is a driver that implements go/packages' fallback behavior.
// It will try to request to an external driver, if one exists. If there's
// no external driver, or the driver returns a response with NotHandled set,
// defaultDriver will fall back to the go list driver.
-func defaultDriver(cfg *Config, patterns ...string) (*driverResponse, error) {
- driver := findExternalDriver(cfg)
- if driver == nil {
- driver = goListDriver
+// The boolean result indicates that an external driver handled the request.
+func defaultDriver(cfg *Config, patterns ...string) (*driverResponse, bool, error) {
+ if driver := findExternalDriver(cfg); driver != nil {
+ response, err := driver(cfg, patterns...)
+ if err != nil {
+ return nil, false, err
+ } else if !response.NotHandled {
+ return response, true, nil
+ }
+ // (fall through)
}
- response, err := driver(cfg, patterns...)
- if err != nil {
- return response, err
- } else if response.NotHandled {
- return goListDriver(cfg, patterns...)
- }
- return response, nil
+
+ response, err := goListDriver(cfg, patterns...)
+ return response, false, err
}
// A Package describes a loaded Go package.
@@ -412,12 +432,6 @@ func init() {
packagesinternal.GetDepsErrors = func(p interface{}) []*packagesinternal.PackageError {
return p.(*Package).depsErrors
}
- packagesinternal.GetGoCmdRunner = func(config interface{}) *gocommand.Runner {
- return config.(*Config).gocmdRunner
- }
- packagesinternal.SetGoCmdRunner = func(config interface{}, runner *gocommand.Runner) {
- config.(*Config).gocmdRunner = runner
- }
packagesinternal.SetModFile = func(config interface{}, value string) {
config.(*Config).modFile = value
}
@@ -554,7 +568,7 @@ type loaderPackage struct {
type loader struct {
pkgs map[string]*loaderPackage
Config
- sizes types.Sizes
+ sizes types.Sizes // non-nil if needed by mode
parseCache map[string]*parseValue
parseCacheMu sync.Mutex
exportMu sync.Mutex // enforces mutual exclusion of exportdata operations
@@ -679,39 +693,38 @@ func (ld *loader) refine(response *driverResponse) ([]*Package, error) {
}
}
- // Materialize the import graph.
+ if ld.Mode&NeedImports != 0 {
+ // Materialize the import graph.
- const (
- white = 0 // new
- grey = 1 // in progress
- black = 2 // complete
- )
+ const (
+ white = 0 // new
+ grey = 1 // in progress
+ black = 2 // complete
+ )
- // visit traverses the import graph, depth-first,
- // and materializes the graph as Packages.Imports.
- //
- // Valid imports are saved in the Packages.Import map.
- // Invalid imports (cycles and missing nodes) are saved in the importErrors map.
- // Thus, even in the presence of both kinds of errors, the Import graph remains a DAG.
- //
- // visit returns whether the package needs src or has a transitive
- // dependency on a package that does. These are the only packages
- // for which we load source code.
- var stack []*loaderPackage
- var visit func(lpkg *loaderPackage) bool
- var srcPkgs []*loaderPackage
- visit = func(lpkg *loaderPackage) bool {
- switch lpkg.color {
- case black:
- return lpkg.needsrc
- case grey:
- panic("internal error: grey node")
- }
- lpkg.color = grey
- stack = append(stack, lpkg) // push
- stubs := lpkg.Imports // the structure form has only stubs with the ID in the Imports
- // If NeedImports isn't set, the imports fields will all be zeroed out.
- if ld.Mode&NeedImports != 0 {
+ // visit traverses the import graph, depth-first,
+ // and materializes the graph as Packages.Imports.
+ //
+ // Valid imports are saved in the Packages.Import map.
+ // Invalid imports (cycles and missing nodes) are saved in the importErrors map.
+ // Thus, even in the presence of both kinds of errors,
+ // the Import graph remains a DAG.
+ //
+ // visit returns whether the package needs src or has a transitive
+ // dependency on a package that does. These are the only packages
+ // for which we load source code.
+ var stack []*loaderPackage
+ var visit func(lpkg *loaderPackage) bool
+ visit = func(lpkg *loaderPackage) bool {
+ switch lpkg.color {
+ case black:
+ return lpkg.needsrc
+ case grey:
+ panic("internal error: grey node")
+ }
+ lpkg.color = grey
+ stack = append(stack, lpkg) // push
+ stubs := lpkg.Imports // the structure form has only stubs with the ID in the Imports
lpkg.Imports = make(map[string]*Package, len(stubs))
for importPath, ipkg := range stubs {
var importErr error
@@ -735,40 +748,39 @@ func (ld *loader) refine(response *driverResponse) ([]*Package, error) {
}
lpkg.Imports[importPath] = imp.Package
}
- }
- if lpkg.needsrc {
- srcPkgs = append(srcPkgs, lpkg)
- }
- if ld.Mode&NeedTypesSizes != 0 {
- lpkg.TypesSizes = ld.sizes
- }
- stack = stack[:len(stack)-1] // pop
- lpkg.color = black
- return lpkg.needsrc
- }
+ // Complete type information is required for the
+ // immediate dependencies of each source package.
+ if lpkg.needsrc && ld.Mode&NeedTypes != 0 {
+ for _, ipkg := range lpkg.Imports {
+ ld.pkgs[ipkg.ID].needtypes = true
+ }
+ }
- if ld.Mode&NeedImports == 0 {
- // We do this to drop the stub import packages that we are not even going to try to resolve.
- for _, lpkg := range initial {
- lpkg.Imports = nil
+ // NeedTypeSizes causes TypeSizes to be set even
+ // on packages for which types aren't needed.
+ if ld.Mode&NeedTypesSizes != 0 {
+ lpkg.TypesSizes = ld.sizes
+ }
+ stack = stack[:len(stack)-1] // pop
+ lpkg.color = black
+
+ return lpkg.needsrc
}
- } else {
+
// For each initial package, create its import DAG.
for _, lpkg := range initial {
visit(lpkg)
}
- }
- if ld.Mode&NeedImports != 0 && ld.Mode&NeedTypes != 0 {
- for _, lpkg := range srcPkgs {
- // Complete type information is required for the
- // immediate dependencies of each source package.
- for _, ipkg := range lpkg.Imports {
- imp := ld.pkgs[ipkg.ID]
- imp.needtypes = true
- }
+
+ } else {
+ // !NeedImports: drop the stub (ID-only) import packages
+ // that we are not even going to try to resolve.
+ for _, lpkg := range initial {
+ lpkg.Imports = nil
}
}
+
// Load type data and syntax if needed, starting at
// the initial packages (roots of the import DAG).
if ld.Mode&NeedTypes != 0 || ld.Mode&NeedSyntax != 0 {
@@ -1002,10 +1014,11 @@ func (ld *loader) loadPackage(lpkg *loaderPackage) {
Defs: make(map[*ast.Ident]types.Object),
Uses: make(map[*ast.Ident]types.Object),
Implicits: make(map[ast.Node]types.Object),
+ Instances: make(map[*ast.Ident]types.Instance),
Scopes: make(map[ast.Node]*types.Scope),
Selections: make(map[*ast.SelectorExpr]*types.Selection),
}
- typeparams.InitInstanceInfo(lpkg.TypesInfo)
+ versions.InitFileVersions(lpkg.TypesInfo)
lpkg.TypesSizes = ld.sizes
importer := importerFunc(func(path string) (*types.Package, error) {
@@ -1043,7 +1056,7 @@ func (ld *loader) loadPackage(lpkg *loaderPackage) {
IgnoreFuncBodies: ld.Mode&NeedDeps == 0 && !lpkg.initial,
Error: appendError,
- Sizes: ld.sizes,
+ Sizes: ld.sizes, // may be nil
}
if lpkg.Module != nil && lpkg.Module.GoVersion != "" {
typesinternal.SetGoVersion(tc, "go"+lpkg.Module.GoVersion)
@@ -1127,7 +1140,7 @@ func (ld *loader) parseFile(filename string) (*ast.File, error) {
var err error
if src == nil {
ioLimit <- true // wait
- src, err = ioutil.ReadFile(filename)
+ src, err = os.ReadFile(filename)
<-ioLimit // signal
}
if err != nil {
diff --git a/vendor/golang.org/x/tools/go/types/objectpath/objectpath.go b/vendor/golang.org/x/tools/go/types/objectpath/objectpath.go
index fa5834baf..11d5c8c3a 100644
--- a/vendor/golang.org/x/tools/go/types/objectpath/objectpath.go
+++ b/vendor/golang.org/x/tools/go/types/objectpath/objectpath.go
@@ -26,13 +26,10 @@ package objectpath
import (
"fmt"
"go/types"
- "sort"
"strconv"
"strings"
- _ "unsafe"
"golang.org/x/tools/internal/typeparams"
- "golang.org/x/tools/internal/typesinternal"
)
// A Path is an opaque name that identifies a types.Object
@@ -123,20 +120,7 @@ func For(obj types.Object) (Path, error) {
// An Encoder amortizes the cost of encoding the paths of multiple objects.
// The zero value of an Encoder is ready to use.
type Encoder struct {
- scopeMemo map[*types.Scope][]types.Object // memoization of scopeObjects
- namedMethodsMemo map[*types.Named][]*types.Func // memoization of namedMethods()
- skipMethodSorting bool
-}
-
-// Expose back doors so that gopls can avoid method sorting, which can dominate
-// analysis on certain repositories.
-//
-// TODO(golang/go#61443): remove this.
-func init() {
- typesinternal.SkipEncoderMethodSorting = func(enc interface{}) {
- enc.(*Encoder).skipMethodSorting = true
- }
- typesinternal.ObjectpathObject = object
+ scopeMemo map[*types.Scope][]types.Object // memoization of scopeObjects
}
// For returns the path to an object relative to its package,
@@ -239,7 +223,7 @@ func (enc *Encoder) For(obj types.Object) (Path, error) {
// Reject obviously non-viable cases.
switch obj := obj.(type) {
case *types.TypeName:
- if _, ok := obj.Type().(*typeparams.TypeParam); !ok {
+ if _, ok := obj.Type().(*types.TypeParam); !ok {
// With the exception of type parameters, only package-level type names
// have a path.
return "", fmt.Errorf("no path for %v", obj)
@@ -299,7 +283,7 @@ func (enc *Encoder) For(obj types.Object) (Path, error) {
}
} else {
if named, _ := T.(*types.Named); named != nil {
- if r := findTypeParam(obj, typeparams.ForNamed(named), path, nil); r != nil {
+ if r := findTypeParam(obj, named.TypeParams(), path, nil); r != nil {
// generic named type
return Path(r), nil
}
@@ -328,31 +312,18 @@ func (enc *Encoder) For(obj types.Object) (Path, error) {
// Inspect declared methods of defined types.
if T, ok := o.Type().(*types.Named); ok {
path = append(path, opType)
- if !enc.skipMethodSorting {
- // Note that method index here is always with respect
- // to canonical ordering of methods, regardless of how
- // they appear in the underlying type.
- for i, m := range enc.namedMethods(T) {
- path2 := appendOpArg(path, opMethod, i)
- if m == obj {
- return Path(path2), nil // found declared method
- }
- if r := find(obj, m.Type(), append(path2, opType), nil); r != nil {
- return Path(r), nil
- }
+ // The method index here is always with respect
+ // to the underlying go/types data structures,
+ // which ultimately derives from source order
+ // and must be preserved by export data.
+ for i := 0; i < T.NumMethods(); i++ {
+ m := T.Method(i)
+ path2 := appendOpArg(path, opMethod, i)
+ if m == obj {
+ return Path(path2), nil // found declared method
}
- } else {
- // This branch must match the logic in the branch above, using go/types
- // APIs without sorting.
- for i := 0; i < T.NumMethods(); i++ {
- m := T.Method(i)
- path2 := appendOpArg(path, opMethod, i)
- if m == obj {
- return Path(path2), nil // found declared method
- }
- if r := find(obj, m.Type(), append(path2, opType), nil); r != nil {
- return Path(r), nil
- }
+ if r := find(obj, m.Type(), append(path2, opType), nil); r != nil {
+ return Path(r), nil
}
}
}
@@ -448,22 +419,13 @@ func (enc *Encoder) concreteMethod(meth *types.Func) (Path, bool) {
path = append(path, name...)
path = append(path, opType)
- if !enc.skipMethodSorting {
- for i, m := range enc.namedMethods(named) {
- if m == meth {
- path = appendOpArg(path, opMethod, i)
- return Path(path), true
- }
- }
- } else {
- // This branch must match the logic of the branch above, using go/types
- // APIs without sorting.
- for i := 0; i < named.NumMethods(); i++ {
- m := named.Method(i)
- if m == meth {
- path = appendOpArg(path, opMethod, i)
- return Path(path), true
- }
+ // Method indices are w.r.t. the go/types data structures,
+ // ultimately deriving from source order,
+ // which is preserved by export data.
+ for i := 0; i < named.NumMethods(); i++ {
+ if named.Method(i) == meth {
+ path = appendOpArg(path, opMethod, i)
+ return Path(path), true
}
}
@@ -500,7 +462,7 @@ func find(obj types.Object, T types.Type, path []byte, seen map[*types.TypeName]
}
return find(obj, T.Elem(), append(path, opElem), seen)
case *types.Signature:
- if r := findTypeParam(obj, typeparams.ForSignature(T), path, seen); r != nil {
+ if r := findTypeParam(obj, T.TypeParams(), path, seen); r != nil {
return r
}
if r := find(obj, T.Params(), append(path, opParams), seen); r != nil {
@@ -543,7 +505,7 @@ func find(obj types.Object, T types.Type, path []byte, seen map[*types.TypeName]
}
}
return nil
- case *typeparams.TypeParam:
+ case *types.TypeParam:
name := T.Obj()
if name == obj {
return append(path, opObj)
@@ -563,7 +525,7 @@ func find(obj types.Object, T types.Type, path []byte, seen map[*types.TypeName]
panic(T)
}
-func findTypeParam(obj types.Object, list *typeparams.TypeParamList, path []byte, seen map[*types.TypeName]bool) []byte {
+func findTypeParam(obj types.Object, list *types.TypeParamList, path []byte, seen map[*types.TypeName]bool) []byte {
for i := 0; i < list.Len(); i++ {
tparam := list.At(i)
path2 := appendOpArg(path, opTypeParam, i)
@@ -576,12 +538,7 @@ func findTypeParam(obj types.Object, list *typeparams.TypeParamList, path []byte
// Object returns the object denoted by path p within the package pkg.
func Object(pkg *types.Package, p Path) (types.Object, error) {
- return object(pkg, string(p), false)
-}
-
-// Note: the skipMethodSorting parameter must match the value of
-// Encoder.skipMethodSorting used during encoding.
-func object(pkg *types.Package, pathstr string, skipMethodSorting bool) (types.Object, error) {
+ pathstr := string(p)
if pathstr == "" {
return nil, fmt.Errorf("empty path")
}
@@ -605,7 +562,7 @@ func object(pkg *types.Package, pathstr string, skipMethodSorting bool) (types.O
}
// abstraction of *types.{Named,Signature}
type hasTypeParams interface {
- TypeParams() *typeparams.TypeParamList
+ TypeParams() *types.TypeParamList
}
// abstraction of *types.{Named,TypeParam}
type hasObj interface {
@@ -707,7 +664,7 @@ func object(pkg *types.Package, pathstr string, skipMethodSorting bool) (types.O
t = tparams.At(index)
case opConstraint:
- tparam, ok := t.(*typeparams.TypeParam)
+ tparam, ok := t.(*types.TypeParam)
if !ok {
return nil, fmt.Errorf("cannot apply %q to %s (got %T, want type parameter)", code, t, t)
}
@@ -747,12 +704,7 @@ func object(pkg *types.Package, pathstr string, skipMethodSorting bool) (types.O
if index >= t.NumMethods() {
return nil, fmt.Errorf("method index %d out of range [0-%d)", index, t.NumMethods())
}
- if skipMethodSorting {
- obj = t.Method(index)
- } else {
- methods := namedMethods(t) // (unmemoized)
- obj = methods[index] // Id-ordered
- }
+ obj = t.Method(index)
default:
return nil, fmt.Errorf("cannot apply %q to %s (got %T, want interface or named)", code, t, t)
@@ -779,33 +731,6 @@ func object(pkg *types.Package, pathstr string, skipMethodSorting bool) (types.O
return obj, nil // success
}
-// namedMethods returns the methods of a Named type in ascending Id order.
-func namedMethods(named *types.Named) []*types.Func {
- methods := make([]*types.Func, named.NumMethods())
- for i := range methods {
- methods[i] = named.Method(i)
- }
- sort.Slice(methods, func(i, j int) bool {
- return methods[i].Id() < methods[j].Id()
- })
- return methods
-}
-
-// namedMethods is a memoization of the namedMethods function. Callers must not modify the result.
-func (enc *Encoder) namedMethods(named *types.Named) []*types.Func {
- m := enc.namedMethodsMemo
- if m == nil {
- m = make(map[*types.Named][]*types.Func)
- enc.namedMethodsMemo = m
- }
- methods, ok := m[named]
- if !ok {
- methods = namedMethods(named) // allocates and sorts
- m[named] = methods
- }
- return methods
-}
-
// scopeObjects is a memoization of scope objects.
// Callers must not modify the result.
func (enc *Encoder) scopeObjects(scope *types.Scope) []types.Object {
diff --git a/vendor/golang.org/x/tools/internal/event/keys/util.go b/vendor/golang.org/x/tools/internal/event/keys/util.go
new file mode 100644
index 000000000..c0e8e731c
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/event/keys/util.go
@@ -0,0 +1,21 @@
+// Copyright 2023 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.
+
+package keys
+
+import (
+ "sort"
+ "strings"
+)
+
+// Join returns a canonical join of the keys in S:
+// a sorted comma-separated string list.
+func Join[S ~[]T, T ~string](s S) string {
+ strs := make([]string, 0, len(s))
+ for _, v := range s {
+ strs = append(strs, string(v))
+ }
+ sort.Strings(strs)
+ return strings.Join(strs, ",")
+}
diff --git a/vendor/golang.org/x/tools/internal/gcimporter/gcimporter.go b/vendor/golang.org/x/tools/internal/gcimporter/gcimporter.go
index b1223713b..2d078ccb1 100644
--- a/vendor/golang.org/x/tools/internal/gcimporter/gcimporter.go
+++ b/vendor/golang.org/x/tools/internal/gcimporter/gcimporter.go
@@ -29,7 +29,6 @@ import (
"go/token"
"go/types"
"io"
- "io/ioutil"
"os"
"os/exec"
"path/filepath"
@@ -221,7 +220,7 @@ func Import(packages map[string]*types.Package, path, srcDir string, lookup func
switch hdr {
case "$$B\n":
var data []byte
- data, err = ioutil.ReadAll(buf)
+ data, err = io.ReadAll(buf)
if err != nil {
break
}
diff --git a/vendor/golang.org/x/tools/internal/gcimporter/iexport.go b/vendor/golang.org/x/tools/internal/gcimporter/iexport.go
index 6103dd710..2ee8c7016 100644
--- a/vendor/golang.org/x/tools/internal/gcimporter/iexport.go
+++ b/vendor/golang.org/x/tools/internal/gcimporter/iexport.go
@@ -24,7 +24,6 @@ import (
"golang.org/x/tools/go/types/objectpath"
"golang.org/x/tools/internal/tokeninternal"
- "golang.org/x/tools/internal/typeparams"
)
// IExportShallow encodes "shallow" export data for the specified package.
@@ -481,7 +480,7 @@ func (p *iexporter) doDecl(obj types.Object) {
}
// Function.
- if typeparams.ForSignature(sig).Len() == 0 {
+ if sig.TypeParams().Len() == 0 {
w.tag('F')
} else {
w.tag('G')
@@ -494,7 +493,7 @@ func (p *iexporter) doDecl(obj types.Object) {
//
// While importing the type parameters, tparamList computes and records
// their export name, so that it can be later used when writing the index.
- if tparams := typeparams.ForSignature(sig); tparams.Len() > 0 {
+ if tparams := sig.TypeParams(); tparams.Len() > 0 {
w.tparamList(obj.Name(), tparams, obj.Pkg())
}
w.signature(sig)
@@ -507,14 +506,14 @@ func (p *iexporter) doDecl(obj types.Object) {
case *types.TypeName:
t := obj.Type()
- if tparam, ok := t.(*typeparams.TypeParam); ok {
+ if tparam, ok := t.(*types.TypeParam); ok {
w.tag('P')
w.pos(obj.Pos())
constraint := tparam.Constraint()
if p.version >= iexportVersionGo1_18 {
implicit := false
if iface, _ := constraint.(*types.Interface); iface != nil {
- implicit = typeparams.IsImplicit(iface)
+ implicit = iface.IsImplicit()
}
w.bool(implicit)
}
@@ -535,17 +534,17 @@ func (p *iexporter) doDecl(obj types.Object) {
panic(internalErrorf("%s is not a defined type", t))
}
- if typeparams.ForNamed(named).Len() == 0 {
+ if named.TypeParams().Len() == 0 {
w.tag('T')
} else {
w.tag('U')
}
w.pos(obj.Pos())
- if typeparams.ForNamed(named).Len() > 0 {
+ if named.TypeParams().Len() > 0 {
// While importing the type parameters, tparamList computes and records
// their export name, so that it can be later used when writing the index.
- w.tparamList(obj.Name(), typeparams.ForNamed(named), obj.Pkg())
+ w.tparamList(obj.Name(), named.TypeParams(), obj.Pkg())
}
underlying := obj.Type().Underlying()
@@ -565,7 +564,7 @@ func (p *iexporter) doDecl(obj types.Object) {
// Receiver type parameters are type arguments of the receiver type, so
// their name must be qualified before exporting recv.
- if rparams := typeparams.RecvTypeParams(sig); rparams.Len() > 0 {
+ if rparams := sig.RecvTypeParams(); rparams.Len() > 0 {
prefix := obj.Name() + "." + m.Name()
for i := 0; i < rparams.Len(); i++ {
rparam := rparams.At(i)
@@ -740,19 +739,19 @@ func (w *exportWriter) doTyp(t types.Type, pkg *types.Package) {
}
switch t := t.(type) {
case *types.Named:
- if targs := typeparams.NamedTypeArgs(t); targs.Len() > 0 {
+ if targs := t.TypeArgs(); targs.Len() > 0 {
w.startType(instanceType)
// TODO(rfindley): investigate if this position is correct, and if it
// matters.
w.pos(t.Obj().Pos())
w.typeList(targs, pkg)
- w.typ(typeparams.NamedTypeOrigin(t), pkg)
+ w.typ(t.Origin(), pkg)
return
}
w.startType(definedType)
w.qualifiedType(t.Obj())
- case *typeparams.TypeParam:
+ case *types.TypeParam:
w.startType(typeParamType)
w.qualifiedType(t.Obj())
@@ -868,7 +867,7 @@ func (w *exportWriter) doTyp(t types.Type, pkg *types.Package) {
w.signature(sig)
}
- case *typeparams.Union:
+ case *types.Union:
w.startType(unionType)
nt := t.Len()
w.uint64(uint64(nt))
@@ -948,14 +947,14 @@ func (w *exportWriter) signature(sig *types.Signature) {
}
}
-func (w *exportWriter) typeList(ts *typeparams.TypeList, pkg *types.Package) {
+func (w *exportWriter) typeList(ts *types.TypeList, pkg *types.Package) {
w.uint64(uint64(ts.Len()))
for i := 0; i < ts.Len(); i++ {
w.typ(ts.At(i), pkg)
}
}
-func (w *exportWriter) tparamList(prefix string, list *typeparams.TypeParamList, pkg *types.Package) {
+func (w *exportWriter) tparamList(prefix string, list *types.TypeParamList, pkg *types.Package) {
ll := uint64(list.Len())
w.uint64(ll)
for i := 0; i < list.Len(); i++ {
@@ -973,7 +972,7 @@ const blankMarker = "$"
// differs from its actual object name: it is prefixed with a qualifier, and
// blank type parameter names are disambiguated by their index in the type
// parameter list.
-func tparamExportName(prefix string, tparam *typeparams.TypeParam) string {
+func tparamExportName(prefix string, tparam *types.TypeParam) string {
assert(prefix != "")
name := tparam.Obj().Name()
if name == "_" {
diff --git a/vendor/golang.org/x/tools/internal/gcimporter/iimport.go b/vendor/golang.org/x/tools/internal/gcimporter/iimport.go
index 8e64cf644..9bde15e3b 100644
--- a/vendor/golang.org/x/tools/internal/gcimporter/iimport.go
+++ b/vendor/golang.org/x/tools/internal/gcimporter/iimport.go
@@ -22,7 +22,6 @@ import (
"strings"
"golang.org/x/tools/go/types/objectpath"
- "golang.org/x/tools/internal/typeparams"
)
type intReader struct {
@@ -321,7 +320,7 @@ func iimportCommon(fset *token.FileSet, getPackages GetPackagesFunc, data []byte
// Therefore, we defer calling SetConstraint there, and call it here instead
// after all types are complete.
for _, d := range p.later {
- typeparams.SetTypeParamConstraint(d.t, d.constraint)
+ d.t.SetConstraint(d.constraint)
}
for _, typ := range p.interfaceList {
@@ -339,7 +338,7 @@ func iimportCommon(fset *token.FileSet, getPackages GetPackagesFunc, data []byte
}
type setConstraintArgs struct {
- t *typeparams.TypeParam
+ t *types.TypeParam
constraint types.Type
}
@@ -549,7 +548,7 @@ func (r *importReader) obj(name string) {
r.declare(types.NewConst(pos, r.currPkg, name, typ, val))
case 'F', 'G':
- var tparams []*typeparams.TypeParam
+ var tparams []*types.TypeParam
if tag == 'G' {
tparams = r.tparamList()
}
@@ -566,7 +565,7 @@ func (r *importReader) obj(name string) {
r.declare(obj)
if tag == 'U' {
tparams := r.tparamList()
- typeparams.SetForNamed(named, tparams)
+ named.SetTypeParams(tparams)
}
underlying := r.p.typAt(r.uint64(), named).Underlying()
@@ -583,12 +582,12 @@ func (r *importReader) obj(name string) {
// typeparams being used in the method sig/body).
base := baseType(recv.Type())
assert(base != nil)
- targs := typeparams.NamedTypeArgs(base)
- var rparams []*typeparams.TypeParam
+ targs := base.TypeArgs()
+ var rparams []*types.TypeParam
if targs.Len() > 0 {
- rparams = make([]*typeparams.TypeParam, targs.Len())
+ rparams = make([]*types.TypeParam, targs.Len())
for i := range rparams {
- rparams[i] = targs.At(i).(*typeparams.TypeParam)
+ rparams[i] = targs.At(i).(*types.TypeParam)
}
}
msig := r.signature(recv, rparams, nil)
@@ -606,7 +605,7 @@ func (r *importReader) obj(name string) {
}
name0 := tparamName(name)
tn := types.NewTypeName(pos, r.currPkg, name0, nil)
- t := typeparams.NewTypeParam(tn, nil)
+ t := types.NewTypeParam(tn, nil)
// To handle recursive references to the typeparam within its
// bound, save the partial type in tparamIndex before reading the bounds.
@@ -622,7 +621,7 @@ func (r *importReader) obj(name string) {
if iface == nil {
errorf("non-interface constraint marked implicit")
}
- typeparams.MarkImplicit(iface)
+ iface.MarkImplicit()
}
// The constraint type may not be complete, if we
// are in the middle of a type recursion involving type
@@ -966,7 +965,7 @@ func (r *importReader) doType(base *types.Named) (res types.Type) {
// The imported instantiated type doesn't include any methods, so
// we must always use the methods of the base (orig) type.
// TODO provide a non-nil *Environment
- t, _ := typeparams.Instantiate(nil, baseType, targs, false)
+ t, _ := types.Instantiate(nil, baseType, targs, false)
// Workaround for golang/go#61561. See the doc for instanceList for details.
r.p.instanceList = append(r.p.instanceList, t)
@@ -976,11 +975,11 @@ func (r *importReader) doType(base *types.Named) (res types.Type) {
if r.p.version < iexportVersionGenerics {
errorf("unexpected instantiation type")
}
- terms := make([]*typeparams.Term, r.uint64())
+ terms := make([]*types.Term, r.uint64())
for i := range terms {
- terms[i] = typeparams.NewTerm(r.bool(), r.typ())
+ terms[i] = types.NewTerm(r.bool(), r.typ())
}
- return typeparams.NewUnion(terms)
+ return types.NewUnion(terms)
}
}
@@ -1008,23 +1007,23 @@ func (r *importReader) objectPathObject() types.Object {
return obj
}
-func (r *importReader) signature(recv *types.Var, rparams []*typeparams.TypeParam, tparams []*typeparams.TypeParam) *types.Signature {
+func (r *importReader) signature(recv *types.Var, rparams []*types.TypeParam, tparams []*types.TypeParam) *types.Signature {
params := r.paramList()
results := r.paramList()
variadic := params.Len() > 0 && r.bool()
- return typeparams.NewSignatureType(recv, rparams, tparams, params, results, variadic)
+ return types.NewSignatureType(recv, rparams, tparams, params, results, variadic)
}
-func (r *importReader) tparamList() []*typeparams.TypeParam {
+func (r *importReader) tparamList() []*types.TypeParam {
n := r.uint64()
if n == 0 {
return nil
}
- xs := make([]*typeparams.TypeParam, n)
+ xs := make([]*types.TypeParam, n)
for i := range xs {
// Note: the standard library importer is tolerant of nil types here,
// though would panic in SetTypeParams.
- xs[i] = r.typ().(*typeparams.TypeParam)
+ xs[i] = r.typ().(*types.TypeParam)
}
return xs
}
diff --git a/vendor/golang.org/x/tools/internal/gocommand/invoke.go b/vendor/golang.org/x/tools/internal/gocommand/invoke.go
index 53cf66da0..55312522d 100644
--- a/vendor/golang.org/x/tools/internal/gocommand/invoke.go
+++ b/vendor/golang.org/x/tools/internal/gocommand/invoke.go
@@ -13,6 +13,7 @@ import (
"io"
"log"
"os"
+ "os/exec"
"reflect"
"regexp"
"runtime"
@@ -21,8 +22,6 @@ import (
"sync"
"time"
- exec "golang.org/x/sys/execabs"
-
"golang.org/x/tools/internal/event"
"golang.org/x/tools/internal/event/keys"
"golang.org/x/tools/internal/event/label"
@@ -85,6 +84,7 @@ func (runner *Runner) RunPiped(ctx context.Context, inv Invocation, stdout, stde
// RunRaw runs the invocation, serializing requests only if they fight over
// go.mod changes.
+// Postcondition: both error results have same nilness.
func (runner *Runner) RunRaw(ctx context.Context, inv Invocation) (*bytes.Buffer, *bytes.Buffer, error, error) {
ctx, done := event.Start(ctx, "gocommand.Runner.RunRaw", invLabels(inv)...)
defer done()
@@ -95,23 +95,24 @@ func (runner *Runner) RunRaw(ctx context.Context, inv Invocation) (*bytes.Buffer
stdout, stderr, friendlyErr, err := runner.runConcurrent(ctx, inv)
// If we encounter a load concurrency error, we need to retry serially.
- if friendlyErr == nil || !modConcurrencyError.MatchString(friendlyErr.Error()) {
- return stdout, stderr, friendlyErr, err
- }
- event.Error(ctx, "Load concurrency error, will retry serially", err)
+ if friendlyErr != nil && modConcurrencyError.MatchString(friendlyErr.Error()) {
+ event.Error(ctx, "Load concurrency error, will retry serially", err)
+
+ // Run serially by calling runPiped.
+ stdout.Reset()
+ stderr.Reset()
+ friendlyErr, err = runner.runPiped(ctx, inv, stdout, stderr)
+ }
- // Run serially by calling runPiped.
- stdout.Reset()
- stderr.Reset()
- friendlyErr, err = runner.runPiped(ctx, inv, stdout, stderr)
return stdout, stderr, friendlyErr, err
}
+// Postcondition: both error results have same nilness.
func (runner *Runner) runConcurrent(ctx context.Context, inv Invocation) (*bytes.Buffer, *bytes.Buffer, error, error) {
// Wait for 1 worker to become available.
select {
case <-ctx.Done():
- return nil, nil, nil, ctx.Err()
+ return nil, nil, ctx.Err(), ctx.Err()
case runner.inFlight <- struct{}{}:
defer func() { <-runner.inFlight }()
}
@@ -121,6 +122,7 @@ func (runner *Runner) runConcurrent(ctx context.Context, inv Invocation) (*bytes
return stdout, stderr, friendlyErr, err
}
+// Postcondition: both error results have same nilness.
func (runner *Runner) runPiped(ctx context.Context, inv Invocation, stdout, stderr io.Writer) (error, error) {
// Make sure the runner is always initialized.
runner.initialize()
@@ -129,7 +131,7 @@ func (runner *Runner) runPiped(ctx context.Context, inv Invocation, stdout, stde
// runPiped commands.
select {
case <-ctx.Done():
- return nil, ctx.Err()
+ return ctx.Err(), ctx.Err()
case runner.serialized <- struct{}{}:
defer func() { <-runner.serialized }()
}
@@ -139,7 +141,7 @@ func (runner *Runner) runPiped(ctx context.Context, inv Invocation, stdout, stde
for i := 0; i < maxInFlight; i++ {
select {
case <-ctx.Done():
- return nil, ctx.Err()
+ return ctx.Err(), ctx.Err()
case runner.inFlight <- struct{}{}:
// Make sure we always "return" any workers we took.
defer func() { <-runner.inFlight }()
@@ -172,6 +174,7 @@ type Invocation struct {
Logf func(format string, args ...interface{})
}
+// Postcondition: both error results have same nilness.
func (i *Invocation) runWithFriendlyError(ctx context.Context, stdout, stderr io.Writer) (friendlyError error, rawError error) {
rawError = i.run(ctx, stdout, stderr)
if rawError != nil {
diff --git a/vendor/golang.org/x/tools/internal/packagesinternal/packages.go b/vendor/golang.org/x/tools/internal/packagesinternal/packages.go
index d9950b1f0..44719de17 100644
--- a/vendor/golang.org/x/tools/internal/packagesinternal/packages.go
+++ b/vendor/golang.org/x/tools/internal/packagesinternal/packages.go
@@ -5,10 +5,6 @@
// Package packagesinternal exposes internal-only fields from go/packages.
package packagesinternal
-import (
- "golang.org/x/tools/internal/gocommand"
-)
-
var GetForTest = func(p interface{}) string { return "" }
var GetDepsErrors = func(p interface{}) []*PackageError { return nil }
@@ -18,10 +14,6 @@ type PackageError struct {
Err string // the error itself
}
-var GetGoCmdRunner = func(config interface{}) *gocommand.Runner { return nil }
-
-var SetGoCmdRunner = func(config interface{}, runner *gocommand.Runner) {}
-
var TypecheckCgo int
var DepsErrors int // must be set as a LoadMode to call GetDepsErrors
var ForTest int // must be set as a LoadMode to call GetForTest
diff --git a/vendor/golang.org/x/tools/internal/typeparams/common.go b/vendor/golang.org/x/tools/internal/typeparams/common.go
index d0d0649fe..cdab98853 100644
--- a/vendor/golang.org/x/tools/internal/typeparams/common.go
+++ b/vendor/golang.org/x/tools/internal/typeparams/common.go
@@ -42,7 +42,7 @@ func UnpackIndexExpr(n ast.Node) (x ast.Expr, lbrack token.Pos, indices []ast.Ex
switch e := n.(type) {
case *ast.IndexExpr:
return e.X, e.Lbrack, []ast.Expr{e.Index}, e.Rbrack
- case *IndexListExpr:
+ case *ast.IndexListExpr:
return e.X, e.Lbrack, e.Indices, e.Rbrack
}
return nil, token.NoPos, nil, token.NoPos
@@ -63,7 +63,7 @@ func PackIndexExpr(x ast.Expr, lbrack token.Pos, indices []ast.Expr, rbrack toke
Rbrack: rbrack,
}
default:
- return &IndexListExpr{
+ return &ast.IndexListExpr{
X: x,
Lbrack: lbrack,
Indices: indices,
@@ -74,7 +74,7 @@ func PackIndexExpr(x ast.Expr, lbrack token.Pos, indices []ast.Expr, rbrack toke
// IsTypeParam reports whether t is a type parameter.
func IsTypeParam(t types.Type) bool {
- _, ok := t.(*TypeParam)
+ _, ok := t.(*types.TypeParam)
return ok
}
@@ -100,11 +100,11 @@ func OriginMethod(fn *types.Func) *types.Func {
// Receiver is a *types.Interface.
return fn
}
- if ForNamed(named).Len() == 0 {
+ if named.TypeParams().Len() == 0 {
// Receiver base has no type parameters, so we can avoid the lookup below.
return fn
}
- orig := NamedTypeOrigin(named)
+ orig := named.Origin()
gfn, _, _ := types.LookupFieldOrMethod(orig, true, fn.Pkg(), fn.Name())
// This is a fix for a gopls crash (#60628) due to a go/types bug (#60634). In:
@@ -157,7 +157,7 @@ func OriginMethod(fn *types.Func) *types.Func {
//
// In this case, GenericAssignableTo reports that instantiations of Container
// are assignable to the corresponding instantiation of Interface.
-func GenericAssignableTo(ctxt *Context, V, T types.Type) bool {
+func GenericAssignableTo(ctxt *types.Context, V, T types.Type) bool {
// If V and T are not both named, or do not have matching non-empty type
// parameter lists, fall back on types.AssignableTo.
@@ -167,9 +167,9 @@ func GenericAssignableTo(ctxt *Context, V, T types.Type) bool {
return types.AssignableTo(V, T)
}
- vtparams := ForNamed(VN)
- ttparams := ForNamed(TN)
- if vtparams.Len() == 0 || vtparams.Len() != ttparams.Len() || NamedTypeArgs(VN).Len() != 0 || NamedTypeArgs(TN).Len() != 0 {
+ vtparams := VN.TypeParams()
+ ttparams := TN.TypeParams()
+ if vtparams.Len() == 0 || vtparams.Len() != ttparams.Len() || VN.TypeArgs().Len() != 0 || TN.TypeArgs().Len() != 0 {
return types.AssignableTo(V, T)
}
@@ -182,7 +182,7 @@ func GenericAssignableTo(ctxt *Context, V, T types.Type) bool {
// Minor optimization: ensure we share a context across the two
// instantiations below.
if ctxt == nil {
- ctxt = NewContext()
+ ctxt = types.NewContext()
}
var targs []types.Type
@@ -190,12 +190,12 @@ func GenericAssignableTo(ctxt *Context, V, T types.Type) bool {
targs = append(targs, vtparams.At(i))
}
- vinst, err := Instantiate(ctxt, V, targs, true)
+ vinst, err := types.Instantiate(ctxt, V, targs, true)
if err != nil {
panic("type parameters should satisfy their own constraints")
}
- tinst, err := Instantiate(ctxt, T, targs, true)
+ tinst, err := types.Instantiate(ctxt, T, targs, true)
if err != nil {
return false
}
diff --git a/vendor/golang.org/x/tools/internal/typeparams/coretype.go b/vendor/golang.org/x/tools/internal/typeparams/coretype.go
index 71248209e..7ea8840ea 100644
--- a/vendor/golang.org/x/tools/internal/typeparams/coretype.go
+++ b/vendor/golang.org/x/tools/internal/typeparams/coretype.go
@@ -108,15 +108,15 @@ func CoreType(T types.Type) types.Type {
//
// _NormalTerms makes no guarantees about the order of terms, except that it
// is deterministic.
-func _NormalTerms(typ types.Type) ([]*Term, error) {
+func _NormalTerms(typ types.Type) ([]*types.Term, error) {
switch typ := typ.(type) {
- case *TypeParam:
+ case *types.TypeParam:
return StructuralTerms(typ)
- case *Union:
+ case *types.Union:
return UnionTermSet(typ)
case *types.Interface:
return InterfaceTermSet(typ)
default:
- return []*Term{NewTerm(false, typ)}, nil
+ return []*types.Term{types.NewTerm(false, typ)}, nil
}
}
diff --git a/vendor/golang.org/x/tools/internal/typeparams/enabled_go117.go b/vendor/golang.org/x/tools/internal/typeparams/enabled_go117.go
deleted file mode 100644
index 18212390e..000000000
--- a/vendor/golang.org/x/tools/internal/typeparams/enabled_go117.go
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright 2021 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 !go1.18
-// +build !go1.18
-
-package typeparams
-
-// Enabled reports whether type parameters are enabled in the current build
-// environment.
-const Enabled = false
diff --git a/vendor/golang.org/x/tools/internal/typeparams/enabled_go118.go b/vendor/golang.org/x/tools/internal/typeparams/enabled_go118.go
deleted file mode 100644
index d67148823..000000000
--- a/vendor/golang.org/x/tools/internal/typeparams/enabled_go118.go
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright 2021 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 go1.18
-// +build go1.18
-
-package typeparams
-
-// Note: this constant is in a separate file as this is the only acceptable
-// diff between the <1.18 API of this package and the 1.18 API.
-
-// Enabled reports whether type parameters are enabled in the current build
-// environment.
-const Enabled = true
diff --git a/vendor/golang.org/x/tools/internal/typeparams/normalize.go b/vendor/golang.org/x/tools/internal/typeparams/normalize.go
index 9c631b651..93c80fdc9 100644
--- a/vendor/golang.org/x/tools/internal/typeparams/normalize.go
+++ b/vendor/golang.org/x/tools/internal/typeparams/normalize.go
@@ -60,7 +60,7 @@ var ErrEmptyTypeSet = errors.New("empty type set")
//
// StructuralTerms makes no guarantees about the order of terms, except that it
// is deterministic.
-func StructuralTerms(tparam *TypeParam) ([]*Term, error) {
+func StructuralTerms(tparam *types.TypeParam) ([]*types.Term, error) {
constraint := tparam.Constraint()
if constraint == nil {
return nil, fmt.Errorf("%s has nil constraint", tparam)
@@ -78,7 +78,7 @@ func StructuralTerms(tparam *TypeParam) ([]*Term, error) {
//
// See the documentation of StructuralTerms for more information on
// normalization.
-func InterfaceTermSet(iface *types.Interface) ([]*Term, error) {
+func InterfaceTermSet(iface *types.Interface) ([]*types.Term, error) {
return computeTermSet(iface)
}
@@ -88,11 +88,11 @@ func InterfaceTermSet(iface *types.Interface) ([]*Term, error) {
//
// See the documentation of StructuralTerms for more information on
// normalization.
-func UnionTermSet(union *Union) ([]*Term, error) {
+func UnionTermSet(union *types.Union) ([]*types.Term, error) {
return computeTermSet(union)
}
-func computeTermSet(typ types.Type) ([]*Term, error) {
+func computeTermSet(typ types.Type) ([]*types.Term, error) {
tset, err := computeTermSetInternal(typ, make(map[types.Type]*termSet), 0)
if err != nil {
return nil, err
@@ -103,9 +103,9 @@ func computeTermSet(typ types.Type) ([]*Term, error) {
if tset.terms.isAll() {
return nil, nil
}
- var terms []*Term
+ var terms []*types.Term
for _, term := range tset.terms {
- terms = append(terms, NewTerm(term.tilde, term.typ))
+ terms = append(terms, types.NewTerm(term.tilde, term.typ))
}
return terms, nil
}
@@ -162,7 +162,7 @@ func computeTermSetInternal(t types.Type, seen map[types.Type]*termSet, depth in
tset.terms = allTermlist
for i := 0; i < u.NumEmbeddeds(); i++ {
embedded := u.EmbeddedType(i)
- if _, ok := embedded.Underlying().(*TypeParam); ok {
+ if _, ok := embedded.Underlying().(*types.TypeParam); ok {
return nil, fmt.Errorf("invalid embedded type %T", embedded)
}
tset2, err := computeTermSetInternal(embedded, seen, depth+1)
@@ -171,7 +171,7 @@ func computeTermSetInternal(t types.Type, seen map[types.Type]*termSet, depth in
}
tset.terms = tset.terms.intersect(tset2.terms)
}
- case *Union:
+ case *types.Union:
// The term set of a union is the union of term sets of its terms.
tset.terms = nil
for i := 0; i < u.Len(); i++ {
@@ -184,7 +184,7 @@ func computeTermSetInternal(t types.Type, seen map[types.Type]*termSet, depth in
return nil, err
}
terms = tset2.terms
- case *TypeParam, *Union:
+ case *types.TypeParam, *types.Union:
// A stand-alone type parameter or union is not permitted as union
// term.
return nil, fmt.Errorf("invalid union term %T", t)
@@ -199,7 +199,7 @@ func computeTermSetInternal(t types.Type, seen map[types.Type]*termSet, depth in
return nil, fmt.Errorf("exceeded max term count %d", maxTermCount)
}
}
- case *TypeParam:
+ case *types.TypeParam:
panic("unreachable")
default:
// For all other types, the term set is just a single non-tilde term
diff --git a/vendor/golang.org/x/tools/internal/typeparams/typeparams_go117.go b/vendor/golang.org/x/tools/internal/typeparams/typeparams_go117.go
deleted file mode 100644
index 7ed86e171..000000000
--- a/vendor/golang.org/x/tools/internal/typeparams/typeparams_go117.go
+++ /dev/null
@@ -1,197 +0,0 @@
-// Copyright 2021 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 !go1.18
-// +build !go1.18
-
-package typeparams
-
-import (
- "go/ast"
- "go/token"
- "go/types"
-)
-
-func unsupported() {
- panic("type parameters are unsupported at this go version")
-}
-
-// IndexListExpr is a placeholder type, as type parameters are not supported at
-// this Go version. Its methods panic on use.
-type IndexListExpr struct {
- ast.Expr
- X ast.Expr // expression
- Lbrack token.Pos // position of "["
- Indices []ast.Expr // index expressions
- Rbrack token.Pos // position of "]"
-}
-
-// ForTypeSpec returns an empty field list, as type parameters on not supported
-// at this Go version.
-func ForTypeSpec(*ast.TypeSpec) *ast.FieldList {
- return nil
-}
-
-// ForFuncType returns an empty field list, as type parameters are not
-// supported at this Go version.
-func ForFuncType(*ast.FuncType) *ast.FieldList {
- return nil
-}
-
-// TypeParam is a placeholder type, as type parameters are not supported at
-// this Go version. Its methods panic on use.
-type TypeParam struct{ types.Type }
-
-func (*TypeParam) Index() int { unsupported(); return 0 }
-func (*TypeParam) Constraint() types.Type { unsupported(); return nil }
-func (*TypeParam) Obj() *types.TypeName { unsupported(); return nil }
-
-// TypeParamList is a placeholder for an empty type parameter list.
-type TypeParamList struct{}
-
-func (*TypeParamList) Len() int { return 0 }
-func (*TypeParamList) At(int) *TypeParam { unsupported(); return nil }
-
-// TypeList is a placeholder for an empty type list.
-type TypeList struct{}
-
-func (*TypeList) Len() int { return 0 }
-func (*TypeList) At(int) types.Type { unsupported(); return nil }
-
-// NewTypeParam is unsupported at this Go version, and panics.
-func NewTypeParam(name *types.TypeName, constraint types.Type) *TypeParam {
- unsupported()
- return nil
-}
-
-// SetTypeParamConstraint is unsupported at this Go version, and panics.
-func SetTypeParamConstraint(tparam *TypeParam, constraint types.Type) {
- unsupported()
-}
-
-// NewSignatureType calls types.NewSignature, panicking if recvTypeParams or
-// typeParams is non-empty.
-func NewSignatureType(recv *types.Var, recvTypeParams, typeParams []*TypeParam, params, results *types.Tuple, variadic bool) *types.Signature {
- if len(recvTypeParams) != 0 || len(typeParams) != 0 {
- panic("signatures cannot have type parameters at this Go version")
- }
- return types.NewSignature(recv, params, results, variadic)
-}
-
-// ForSignature returns an empty slice.
-func ForSignature(*types.Signature) *TypeParamList {
- return nil
-}
-
-// RecvTypeParams returns a nil slice.
-func RecvTypeParams(sig *types.Signature) *TypeParamList {
- return nil
-}
-
-// IsComparable returns false, as no interfaces are type-restricted at this Go
-// version.
-func IsComparable(*types.Interface) bool {
- return false
-}
-
-// IsMethodSet returns true, as no interfaces are type-restricted at this Go
-// version.
-func IsMethodSet(*types.Interface) bool {
- return true
-}
-
-// IsImplicit returns false, as no interfaces are implicit at this Go version.
-func IsImplicit(*types.Interface) bool {
- return false
-}
-
-// MarkImplicit does nothing, because this Go version does not have implicit
-// interfaces.
-func MarkImplicit(*types.Interface) {}
-
-// ForNamed returns an empty type parameter list, as type parameters are not
-// supported at this Go version.
-func ForNamed(*types.Named) *TypeParamList {
- return nil
-}
-
-// SetForNamed panics if tparams is non-empty.
-func SetForNamed(_ *types.Named, tparams []*TypeParam) {
- if len(tparams) > 0 {
- unsupported()
- }
-}
-
-// NamedTypeArgs returns nil.
-func NamedTypeArgs(*types.Named) *TypeList {
- return nil
-}
-
-// NamedTypeOrigin is the identity method at this Go version.
-func NamedTypeOrigin(named *types.Named) *types.Named {
- return named
-}
-
-// Term holds information about a structural type restriction.
-type Term struct {
- tilde bool
- typ types.Type
-}
-
-func (m *Term) Tilde() bool { return m.tilde }
-func (m *Term) Type() types.Type { return m.typ }
-func (m *Term) String() string {
- pre := ""
- if m.tilde {
- pre = "~"
- }
- return pre + m.typ.String()
-}
-
-// NewTerm is unsupported at this Go version, and panics.
-func NewTerm(tilde bool, typ types.Type) *Term {
- return &Term{tilde, typ}
-}
-
-// Union is a placeholder type, as type parameters are not supported at this Go
-// version. Its methods panic on use.
-type Union struct{ types.Type }
-
-func (*Union) Len() int { return 0 }
-func (*Union) Term(i int) *Term { unsupported(); return nil }
-
-// NewUnion is unsupported at this Go version, and panics.
-func NewUnion(terms []*Term) *Union {
- unsupported()
- return nil
-}
-
-// InitInstanceInfo is a noop at this Go version.
-func InitInstanceInfo(*types.Info) {}
-
-// Instance is a placeholder type, as type parameters are not supported at this
-// Go version.
-type Instance struct {
- TypeArgs *TypeList
- Type types.Type
-}
-
-// GetInstances returns a nil map, as type parameters are not supported at this
-// Go version.
-func GetInstances(info *types.Info) map[*ast.Ident]Instance { return nil }
-
-// Context is a placeholder type, as type parameters are not supported at
-// this Go version.
-type Context struct{}
-
-// NewContext returns a placeholder Context instance.
-func NewContext() *Context {
- return &Context{}
-}
-
-// Instantiate is unsupported on this Go version, and panics.
-func Instantiate(ctxt *Context, typ types.Type, targs []types.Type, validate bool) (types.Type, error) {
- unsupported()
- return nil, nil
-}
diff --git a/vendor/golang.org/x/tools/internal/typeparams/typeparams_go118.go b/vendor/golang.org/x/tools/internal/typeparams/typeparams_go118.go
deleted file mode 100644
index cf301af1d..000000000
--- a/vendor/golang.org/x/tools/internal/typeparams/typeparams_go118.go
+++ /dev/null
@@ -1,151 +0,0 @@
-// Copyright 2021 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 go1.18
-// +build go1.18
-
-package typeparams
-
-import (
- "go/ast"
- "go/types"
-)
-
-// IndexListExpr is an alias for ast.IndexListExpr.
-type IndexListExpr = ast.IndexListExpr
-
-// ForTypeSpec returns n.TypeParams.
-func ForTypeSpec(n *ast.TypeSpec) *ast.FieldList {
- if n == nil {
- return nil
- }
- return n.TypeParams
-}
-
-// ForFuncType returns n.TypeParams.
-func ForFuncType(n *ast.FuncType) *ast.FieldList {
- if n == nil {
- return nil
- }
- return n.TypeParams
-}
-
-// TypeParam is an alias for types.TypeParam
-type TypeParam = types.TypeParam
-
-// TypeParamList is an alias for types.TypeParamList
-type TypeParamList = types.TypeParamList
-
-// TypeList is an alias for types.TypeList
-type TypeList = types.TypeList
-
-// NewTypeParam calls types.NewTypeParam.
-func NewTypeParam(name *types.TypeName, constraint types.Type) *TypeParam {
- return types.NewTypeParam(name, constraint)
-}
-
-// SetTypeParamConstraint calls tparam.SetConstraint(constraint).
-func SetTypeParamConstraint(tparam *TypeParam, constraint types.Type) {
- tparam.SetConstraint(constraint)
-}
-
-// NewSignatureType calls types.NewSignatureType.
-func NewSignatureType(recv *types.Var, recvTypeParams, typeParams []*TypeParam, params, results *types.Tuple, variadic bool) *types.Signature {
- return types.NewSignatureType(recv, recvTypeParams, typeParams, params, results, variadic)
-}
-
-// ForSignature returns sig.TypeParams()
-func ForSignature(sig *types.Signature) *TypeParamList {
- return sig.TypeParams()
-}
-
-// RecvTypeParams returns sig.RecvTypeParams().
-func RecvTypeParams(sig *types.Signature) *TypeParamList {
- return sig.RecvTypeParams()
-}
-
-// IsComparable calls iface.IsComparable().
-func IsComparable(iface *types.Interface) bool {
- return iface.IsComparable()
-}
-
-// IsMethodSet calls iface.IsMethodSet().
-func IsMethodSet(iface *types.Interface) bool {
- return iface.IsMethodSet()
-}
-
-// IsImplicit calls iface.IsImplicit().
-func IsImplicit(iface *types.Interface) bool {
- return iface.IsImplicit()
-}
-
-// MarkImplicit calls iface.MarkImplicit().
-func MarkImplicit(iface *types.Interface) {
- iface.MarkImplicit()
-}
-
-// ForNamed extracts the (possibly empty) type parameter object list from
-// named.
-func ForNamed(named *types.Named) *TypeParamList {
- return named.TypeParams()
-}
-
-// SetForNamed sets the type params tparams on n. Each tparam must be of
-// dynamic type *types.TypeParam.
-func SetForNamed(n *types.Named, tparams []*TypeParam) {
- n.SetTypeParams(tparams)
-}
-
-// NamedTypeArgs returns named.TypeArgs().
-func NamedTypeArgs(named *types.Named) *TypeList {
- return named.TypeArgs()
-}
-
-// NamedTypeOrigin returns named.Orig().
-func NamedTypeOrigin(named *types.Named) *types.Named {
- return named.Origin()
-}
-
-// Term is an alias for types.Term.
-type Term = types.Term
-
-// NewTerm calls types.NewTerm.
-func NewTerm(tilde bool, typ types.Type) *Term {
- return types.NewTerm(tilde, typ)
-}
-
-// Union is an alias for types.Union
-type Union = types.Union
-
-// NewUnion calls types.NewUnion.
-func NewUnion(terms []*Term) *Union {
- return types.NewUnion(terms)
-}
-
-// InitInstanceInfo initializes info to record information about type and
-// function instances.
-func InitInstanceInfo(info *types.Info) {
- info.Instances = make(map[*ast.Ident]types.Instance)
-}
-
-// Instance is an alias for types.Instance.
-type Instance = types.Instance
-
-// GetInstances returns info.Instances.
-func GetInstances(info *types.Info) map[*ast.Ident]Instance {
- return info.Instances
-}
-
-// Context is an alias for types.Context.
-type Context = types.Context
-
-// NewContext calls types.NewContext.
-func NewContext() *Context {
- return types.NewContext()
-}
-
-// Instantiate calls types.Instantiate.
-func Instantiate(ctxt *Context, typ types.Type, targs []types.Type, validate bool) (types.Type, error) {
- return types.Instantiate(ctxt, typ, targs, validate)
-}
diff --git a/vendor/golang.org/x/tools/internal/typesinternal/objectpath.go b/vendor/golang.org/x/tools/internal/typesinternal/objectpath.go
deleted file mode 100644
index 5e96e8955..000000000
--- a/vendor/golang.org/x/tools/internal/typesinternal/objectpath.go
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright 2023 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.
-
-package typesinternal
-
-import "go/types"
-
-// This file contains back doors that allow gopls to avoid method sorting when
-// using the objectpath package.
-//
-// This is performance-critical in certain repositories, but changing the
-// behavior of the objectpath package is still being discussed in
-// golang/go#61443. If we decide to remove the sorting in objectpath we can
-// simply delete these back doors. Otherwise, we should add a new API to
-// objectpath that allows controlling the sorting.
-
-// SkipEncoderMethodSorting marks enc (which must be an *objectpath.Encoder) as
-// not requiring sorted methods.
-var SkipEncoderMethodSorting func(enc interface{})
-
-// ObjectpathObject is like objectpath.Object, but allows suppressing method
-// sorting.
-var ObjectpathObject func(pkg *types.Package, p string, skipMethodSorting bool) (types.Object, error)
diff --git a/vendor/golang.org/x/tools/internal/versions/gover.go b/vendor/golang.org/x/tools/internal/versions/gover.go
new file mode 100644
index 000000000..bbabcd22e
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/versions/gover.go
@@ -0,0 +1,172 @@
+// Copyright 2023 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.
+
+// This is a fork of internal/gover for use by x/tools until
+// go1.21 and earlier are no longer supported by x/tools.
+
+package versions
+
+import "strings"
+
+// A gover is a parsed Go gover: major[.Minor[.Patch]][kind[pre]]
+// The numbers are the original decimal strings to avoid integer overflows
+// and since there is very little actual math. (Probably overflow doesn't matter in practice,
+// but at the time this code was written, there was an existing test that used
+// go1.99999999999, which does not fit in an int on 32-bit platforms.
+// The "big decimal" representation avoids the problem entirely.)
+type gover struct {
+ major string // decimal
+ minor string // decimal or ""
+ patch string // decimal or ""
+ kind string // "", "alpha", "beta", "rc"
+ pre string // decimal or ""
+}
+
+// compare returns -1, 0, or +1 depending on whether
+// x < y, x == y, or x > y, interpreted as toolchain versions.
+// The versions x and y must not begin with a "go" prefix: just "1.21" not "go1.21".
+// Malformed versions compare less than well-formed versions and equal to each other.
+// The language version "1.21" compares less than the release candidate and eventual releases "1.21rc1" and "1.21.0".
+func compare(x, y string) int {
+ vx := parse(x)
+ vy := parse(y)
+
+ if c := cmpInt(vx.major, vy.major); c != 0 {
+ return c
+ }
+ if c := cmpInt(vx.minor, vy.minor); c != 0 {
+ return c
+ }
+ if c := cmpInt(vx.patch, vy.patch); c != 0 {
+ return c
+ }
+ if c := strings.Compare(vx.kind, vy.kind); c != 0 { // "" < alpha < beta < rc
+ return c
+ }
+ if c := cmpInt(vx.pre, vy.pre); c != 0 {
+ return c
+ }
+ return 0
+}
+
+// lang returns the Go language version. For example, lang("1.2.3") == "1.2".
+func lang(x string) string {
+ v := parse(x)
+ if v.minor == "" || v.major == "1" && v.minor == "0" {
+ return v.major
+ }
+ return v.major + "." + v.minor
+}
+
+// isValid reports whether the version x is valid.
+func isValid(x string) bool {
+ return parse(x) != gover{}
+}
+
+// parse parses the Go version string x into a version.
+// It returns the zero version if x is malformed.
+func parse(x string) gover {
+ var v gover
+
+ // Parse major version.
+ var ok bool
+ v.major, x, ok = cutInt(x)
+ if !ok {
+ return gover{}
+ }
+ if x == "" {
+ // Interpret "1" as "1.0.0".
+ v.minor = "0"
+ v.patch = "0"
+ return v
+ }
+
+ // Parse . before minor version.
+ if x[0] != '.' {
+ return gover{}
+ }
+
+ // Parse minor version.
+ v.minor, x, ok = cutInt(x[1:])
+ if !ok {
+ return gover{}
+ }
+ if x == "" {
+ // Patch missing is same as "0" for older versions.
+ // Starting in Go 1.21, patch missing is different from explicit .0.
+ if cmpInt(v.minor, "21") < 0 {
+ v.patch = "0"
+ }
+ return v
+ }
+
+ // Parse patch if present.
+ if x[0] == '.' {
+ v.patch, x, ok = cutInt(x[1:])
+ if !ok || x != "" {
+ // Note that we are disallowing prereleases (alpha, beta, rc) for patch releases here (x != "").
+ // Allowing them would be a bit confusing because we already have:
+ // 1.21 < 1.21rc1
+ // But a prerelease of a patch would have the opposite effect:
+ // 1.21.3rc1 < 1.21.3
+ // We've never needed them before, so let's not start now.
+ return gover{}
+ }
+ return v
+ }
+
+ // Parse prerelease.
+ i := 0
+ for i < len(x) && (x[i] < '0' || '9' < x[i]) {
+ if x[i] < 'a' || 'z' < x[i] {
+ return gover{}
+ }
+ i++
+ }
+ if i == 0 {
+ return gover{}
+ }
+ v.kind, x = x[:i], x[i:]
+ if x == "" {
+ return v
+ }
+ v.pre, x, ok = cutInt(x)
+ if !ok || x != "" {
+ return gover{}
+ }
+
+ return v
+}
+
+// cutInt scans the leading decimal number at the start of x to an integer
+// and returns that value and the rest of the string.
+func cutInt(x string) (n, rest string, ok bool) {
+ i := 0
+ for i < len(x) && '0' <= x[i] && x[i] <= '9' {
+ i++
+ }
+ if i == 0 || x[0] == '0' && i != 1 { // no digits or unnecessary leading zero
+ return "", "", false
+ }
+ return x[:i], x[i:], true
+}
+
+// cmpInt returns cmp.Compare(x, y) interpreting x and y as decimal numbers.
+// (Copied from golang.org/x/mod/semver's compareInt.)
+func cmpInt(x, y string) int {
+ if x == y {
+ return 0
+ }
+ if len(x) < len(y) {
+ return -1
+ }
+ if len(x) > len(y) {
+ return +1
+ }
+ if x < y {
+ return -1
+ } else {
+ return +1
+ }
+}
diff --git a/vendor/golang.org/x/tools/internal/versions/types.go b/vendor/golang.org/x/tools/internal/versions/types.go
new file mode 100644
index 000000000..562eef21f
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/versions/types.go
@@ -0,0 +1,19 @@
+// Copyright 2023 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.
+
+package versions
+
+import (
+ "go/types"
+)
+
+// GoVersion returns the Go version of the type package.
+// It returns zero if no version can be determined.
+func GoVersion(pkg *types.Package) string {
+ // TODO(taking): x/tools can call GoVersion() [from 1.21] after 1.25.
+ if pkg, ok := any(pkg).(interface{ GoVersion() string }); ok {
+ return pkg.GoVersion()
+ }
+ return ""
+}
diff --git a/vendor/golang.org/x/tools/internal/versions/types_go121.go b/vendor/golang.org/x/tools/internal/versions/types_go121.go
new file mode 100644
index 000000000..a7b79207a
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/versions/types_go121.go
@@ -0,0 +1,20 @@
+// Copyright 2023 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 !go1.22
+// +build !go1.22
+
+package versions
+
+import (
+ "go/ast"
+ "go/types"
+)
+
+// FileVersions always reports the a file's Go version as the
+// zero version at this Go version.
+func FileVersions(info *types.Info, file *ast.File) string { return "" }
+
+// InitFileVersions is a noop at this Go version.
+func InitFileVersions(*types.Info) {}
diff --git a/vendor/golang.org/x/tools/internal/versions/types_go122.go b/vendor/golang.org/x/tools/internal/versions/types_go122.go
new file mode 100644
index 000000000..7b9ba89a8
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/versions/types_go122.go
@@ -0,0 +1,24 @@
+// Copyright 2023 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 go1.22
+// +build go1.22
+
+package versions
+
+import (
+ "go/ast"
+ "go/types"
+)
+
+// FileVersions maps a file to the file's semantic Go version.
+// The reported version is the zero version if a version cannot be determined.
+func FileVersions(info *types.Info, file *ast.File) string {
+ return info.FileVersions[file]
+}
+
+// InitFileVersions initializes info to record Go versions for Go files.
+func InitFileVersions(info *types.Info) {
+ info.FileVersions = make(map[*ast.File]string)
+}
diff --git a/vendor/golang.org/x/tools/internal/versions/versions.go b/vendor/golang.org/x/tools/internal/versions/versions.go
new file mode 100644
index 000000000..e16f6c33a
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/versions/versions.go
@@ -0,0 +1,52 @@
+// Copyright 2023 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.
+
+package versions
+
+// Note: If we use build tags to use go/versions when go >=1.22,
+// we run into go.dev/issue/53737. Under some operations users would see an
+// import of "go/versions" even if they would not compile the file.
+// For example, during `go get -u ./...` (go.dev/issue/64490) we do not try to include
+// For this reason, this library just a clone of go/versions for the moment.
+
+// Lang returns the Go language version for version x.
+// If x is not a valid version, Lang returns the empty string.
+// For example:
+//
+// Lang("go1.21rc2") = "go1.21"
+// Lang("go1.21.2") = "go1.21"
+// Lang("go1.21") = "go1.21"
+// Lang("go1") = "go1"
+// Lang("bad") = ""
+// Lang("1.21") = ""
+func Lang(x string) string {
+ v := lang(stripGo(x))
+ if v == "" {
+ return ""
+ }
+ return x[:2+len(v)] // "go"+v without allocation
+}
+
+// Compare returns -1, 0, or +1 depending on whether
+// x < y, x == y, or x > y, interpreted as Go versions.
+// The versions x and y must begin with a "go" prefix: "go1.21" not "1.21".
+// Invalid versions, including the empty string, compare less than
+// valid versions and equal to each other.
+// The language version "go1.21" compares less than the
+// release candidate and eventual releases "go1.21rc1" and "go1.21.0".
+// Custom toolchain suffixes are ignored during comparison:
+// "go1.21.0" and "go1.21.0-bigcorp" are equal.
+func Compare(x, y string) int { return compare(stripGo(x), stripGo(y)) }
+
+// IsValid reports whether the version x is valid.
+func IsValid(x string) bool { return isValid(stripGo(x)) }
+
+// stripGo converts from a "go1.21" version to a "1.21" version.
+// If v does not start with "go", stripGo returns the empty string (a known invalid version).
+func stripGo(v string) string {
+ if len(v) < 2 || v[:2] != "go" {
+ return ""
+ }
+ return v[2:]
+}
diff --git a/vendor/modules.txt b/vendor/modules.txt
index 06d5b3f77..9ecd252ad 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -147,7 +147,7 @@ github.com/coreos/go-systemd/v22/dbus
# github.com/cornelk/hashmap v1.0.8
## explicit; go 1.19
github.com/cornelk/hashmap
-# github.com/davecgh/go-spew v1.1.1
+# github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc
## explicit
github.com/davecgh/go-spew/spew
# github.com/disintegration/imaging v1.6.2
@@ -416,7 +416,7 @@ github.com/oklog/ulid
# github.com/opencontainers/runtime-spec v1.0.2
## explicit
github.com/opencontainers/runtime-spec/specs-go
-# github.com/pelletier/go-toml/v2 v2.1.0
+# github.com/pelletier/go-toml/v2 v2.1.1
## explicit; go 1.16
github.com/pelletier/go-toml/v2
github.com/pelletier/go-toml/v2/internal/characters
@@ -426,7 +426,7 @@ github.com/pelletier/go-toml/v2/unstable
# github.com/pkg/errors v0.9.1
## explicit
github.com/pkg/errors
-# github.com/pmezard/go-difflib v1.0.0
+# github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2
## explicit
github.com/pmezard/go-difflib/difflib
# github.com/prometheus/client_golang v1.18.0
@@ -456,28 +456,37 @@ github.com/remyoudompheng/bigfft
# github.com/rs/xid v1.5.0
## explicit; go 1.12
github.com/rs/xid
+# github.com/sagikazarmark/locafero v0.4.0
+## explicit; go 1.20
+github.com/sagikazarmark/locafero
+# github.com/sagikazarmark/slog-shim v0.1.0
+## explicit; go 1.20
+github.com/sagikazarmark/slog-shim
# github.com/sirupsen/logrus v1.9.3
## explicit; go 1.13
github.com/sirupsen/logrus
-# github.com/spf13/afero v1.9.5
-## explicit; go 1.16
+# github.com/sourcegraph/conc v0.3.0
+## explicit; go 1.19
+github.com/sourcegraph/conc
+github.com/sourcegraph/conc/internal/multierror
+github.com/sourcegraph/conc/iter
+github.com/sourcegraph/conc/panics
+# github.com/spf13/afero v1.11.0
+## explicit; go 1.19
github.com/spf13/afero
github.com/spf13/afero/internal/common
github.com/spf13/afero/mem
-# github.com/spf13/cast v1.5.1
-## explicit; go 1.18
+# github.com/spf13/cast v1.6.0
+## explicit; go 1.19
github.com/spf13/cast
# github.com/spf13/cobra v1.8.0
## explicit; go 1.15
github.com/spf13/cobra
-# github.com/spf13/jwalterweatherman v1.1.0
-## explicit
-github.com/spf13/jwalterweatherman
# github.com/spf13/pflag v1.0.5
## explicit; go 1.12
github.com/spf13/pflag
-# github.com/spf13/viper v1.16.0
-## explicit; go 1.17
+# github.com/spf13/viper v1.18.2
+## explicit; go 1.18
github.com/spf13/viper
github.com/spf13/viper/internal/encoding
github.com/spf13/viper/internal/encoding/dotenv
@@ -487,12 +496,13 @@ github.com/spf13/viper/internal/encoding/javaproperties
github.com/spf13/viper/internal/encoding/json
github.com/spf13/viper/internal/encoding/toml
github.com/spf13/viper/internal/encoding/yaml
+github.com/spf13/viper/internal/features
# github.com/stretchr/testify v1.8.4
## explicit; go 1.20
github.com/stretchr/testify/assert
github.com/stretchr/testify/require
github.com/stretchr/testify/suite
-# github.com/subosito/gotenv v1.4.2
+# github.com/subosito/gotenv v1.6.0
## explicit; go 1.18
github.com/subosito/gotenv
# github.com/superseriousbusiness/activity v1.4.0-gts
@@ -842,6 +852,9 @@ go.opentelemetry.io/proto/otlp/trace/v1
go.uber.org/automaxprocs/internal/cgroups
go.uber.org/automaxprocs/internal/runtime
go.uber.org/automaxprocs/maxprocs
+# go.uber.org/multierr v1.11.0
+## explicit; go 1.19
+go.uber.org/multierr
# golang.org/x/arch v0.5.0
## explicit; go 1.17
golang.org/x/arch/x86/x86asm
@@ -865,10 +878,13 @@ golang.org/x/crypto/ripemd160
golang.org/x/crypto/sha3
golang.org/x/crypto/ssh
golang.org/x/crypto/ssh/internal/bcrypt_pbkdf
-# golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1
+# golang.org/x/exp v0.0.0-20240112132812-db7319d0e0e3
## explicit; go 1.20
golang.org/x/exp/constraints
golang.org/x/exp/slices
+golang.org/x/exp/slog
+golang.org/x/exp/slog/internal
+golang.org/x/exp/slog/internal/buffer
# golang.org/x/image v0.15.0
## explicit; go 1.18
golang.org/x/image/bmp
@@ -879,8 +895,8 @@ golang.org/x/image/tiff/lzw
golang.org/x/image/vp8
golang.org/x/image/vp8l
golang.org/x/image/webp
-# golang.org/x/mod v0.12.0
-## explicit; go 1.17
+# golang.org/x/mod v0.14.0
+## explicit; go 1.18
golang.org/x/mod/semver
# golang.org/x/net v0.20.0
## explicit; go 1.18
@@ -906,24 +922,28 @@ golang.org/x/net/trace
## explicit; go 1.18
golang.org/x/oauth2
golang.org/x/oauth2/internal
-# golang.org/x/sync v0.4.0
-## explicit; go 1.17
+# golang.org/x/sync v0.6.0
+## explicit; go 1.18
golang.org/x/sync/semaphore
# golang.org/x/sys v0.16.0
## explicit; go 1.18
golang.org/x/sys/cpu
-golang.org/x/sys/execabs
golang.org/x/sys/unix
golang.org/x/sys/windows
golang.org/x/sys/windows/registry
# golang.org/x/text v0.14.0
## explicit; go 1.18
golang.org/x/text/cases
+golang.org/x/text/encoding
+golang.org/x/text/encoding/internal
+golang.org/x/text/encoding/internal/identifier
+golang.org/x/text/encoding/unicode
golang.org/x/text/internal
golang.org/x/text/internal/format
golang.org/x/text/internal/language
golang.org/x/text/internal/language/compact
golang.org/x/text/internal/tag
+golang.org/x/text/internal/utf8internal
golang.org/x/text/language
golang.org/x/text/language/display
golang.org/x/text/runes
@@ -933,7 +953,7 @@ golang.org/x/text/transform
golang.org/x/text/unicode/bidi
golang.org/x/text/unicode/norm
golang.org/x/text/width
-# golang.org/x/tools v0.13.0
+# golang.org/x/tools v0.17.0
## explicit; go 1.18
golang.org/x/tools/go/gcexportdata
golang.org/x/tools/go/internal/packagesdriver
@@ -951,6 +971,7 @@ golang.org/x/tools/internal/pkgbits
golang.org/x/tools/internal/tokeninternal
golang.org/x/tools/internal/typeparams
golang.org/x/tools/internal/typesinternal
+golang.org/x/tools/internal/versions
# google.golang.org/appengine v1.6.8
## explicit; go 1.11
google.golang.org/appengine/internal
@@ -960,10 +981,10 @@ google.golang.org/appengine/internal/log
google.golang.org/appengine/internal/remote_api
google.golang.org/appengine/internal/urlfetch
google.golang.org/appengine/urlfetch
-# google.golang.org/genproto/googleapis/api v0.0.0-20230822172742-b8732ec3820d
+# google.golang.org/genproto/googleapis/api v0.0.0-20231106174013-bbf56f31fb17
## explicit; go 1.19
google.golang.org/genproto/googleapis/api/httpbody
-# google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d
+# google.golang.org/genproto/googleapis/rpc v0.0.0-20231120223509-83a465c0220f
## explicit; go 1.19
google.golang.org/genproto/googleapis/rpc/errdetails
google.golang.org/genproto/googleapis/rpc/status